Reputation: 7736
I'm currently using Angular 1.5
library and wants to create a component for simple Text Box like below.
'use strict';
angular
.module('components')
.component('inputBox', {
bindings: {
label: '@',
name: '@',
type: '@',
classes: '@',
placeholder: '@',
maxlength: '@'
},
controllerAs: 'field',
templateUrl: 'app/components/inputBox.html'
});
<input type="{{field.type || 'text'}}"
class="form-control {{field.classes}}"
id="{{field.name}}"
name="{{field.name || 'unnamed'}}"
maxlength="{{field.maxlength}}"
placeholder="{{field.placeholder}}" />
<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.
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.
Upvotes: 0
Views: 1106
Reputation: 29
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
Upvotes: 0
Reputation: 1040
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?
Upvotes: 1