0

I'm currently using Angular 1.5 library and wants to create a component for simple Text Box like below.

Component JS

'use strict';

angular
    .module('components')
    .component('inputBox', {
        bindings: {
            label: '@',
            name: '@',
            type: '@',
            classes: '@',
            placeholder: '@',
            maxlength: '@'
        },
        controllerAs: 'field',
        templateUrl: 'app/components/inputBox.html'
    });

Component Template

<input type="{{field.type || 'text'}}"  
            class="form-control {{field.classes}}" 
            id="{{field.name}}" 
            name="{{field.name || 'unnamed'}}" 
            maxlength="{{field.maxlength}}" 
            placeholder="{{field.placeholder}}" />

Usage in all Templates.

<input-box 
    label="Enter an account"
    name="accountNumber"
    type="number"
    classes="form-control"
    placeholder="Account Number"
    maxlength="20"

    // directives
    ng-model="accountNumber"
    ng-custom1="value1" 
    ng-custom2="value2" 
    ng-custom-validator="value4" />

I have two issues which is below where i need the best practices.

  1. I want to keep all directives extended in the usage template not part of component.
  2. Which is best practice @ or = but i good understanding about this options.

    a. "@" ( Text binding / one-way binding )

    b. "=" ( Direct model binding / two-way binding )

    c. "&" ( Behaviour binding / Method binding )

Why this approach?

I have around 27 forms with many input types. I want to create the single component that will have all field label, input and error container.

Venkat.R
  • 7,420
  • 5
  • 42
  • 63

2 Answers2

1

There are some things quite confusing or just wrong:

You are passing the name of your model like

<input-box modelname="account.number"...

and try to use it with:

<input type="{{field.type || 'text'}}" 
        ng-model="account.number" ...

You are not using your modelname, instead you are trying to access a object variable account.number which is not defined (at least it is not defined in your example) this is not dynamic anymore.

If you want to pass your model directly do something like:

angular
.module('components')
.component('inputBox', {
    bindings: {
        model: '=',
        ...
    },
    controllerAs: 'field',
    templateUrl: 'app/components/inputBox.html'
});

with

<input-box model="account" ... />

And in your component template:

<input ng-model="model" ... />

Regarding your second question: you can´t do

<input ... {{field.attribs}} />

You could use attrs for that and copying them to your input element:

angular
.module('components')
.component('inputBox', {
    bindings: {
        model: '=',
        ...
    },
    controllerAs: 'field',
    templateUrl: 'app/components/inputBox.html',
    controller: function($scope, $element, $attrs) {
        angular.forEach($attrs, function(key, value){
            $element[key] = value;
        });
    }
});

At least i am wondering why to wrap an input element into a component and do nothing more than copy the properties, what do you want to achieve?

kabaehr
  • 1,040
  • 11
  • 18
  • Thanks for your reply. updated my question whatever you are looking for ? BTW, your answer is not answer the question – Venkat.R Apr 20 '16 at 06:31
0

The Angular team recommends scope isolation for components by using one-way binding <or @ rather than two-way binding =. In terms of getting values out of a component, the recommendation is to use events.

Full details here under the section Component based application architecture

T Dog
  • 29
  • 4