Reputation: 114
I'm trying to create a custom form component which I can use ng-model
to bind with. I've found loads of tutorials on how to do this with directives, but I can't seem to figure out how to do it with components as you can't have link
functions with components, and trying to pass in the ngModel
dependency to the controller results in this error:
Error: [$injector:unpr] Unknown provider: $ngModelProvider <- $ngModel
I've also seen this and tried this:
bindings: {
value: "=ngModel"
}
I tried that, and then setting value in the controller for two way binding, but it doesn't seem to work.
Upvotes: 1
Views: 2763
Reputation: 338
I think the angular-recommended way of doing callbacks (like ngclick for example) is to use the method binding type: &
Here is a plunkr example: https://plnkr.co/edit/nySL4OoMpJPkGXX8j78U?p=preview
Note this part, the method binding type is defines, and the internalChange function executes whatever angular expression is provided by the parent/caller.
bindings: {
valueChanged: '&?'
},
controller: function() {
this.$onInit = function() {
this.value = 'initial value';
};
this.internalChange = function() {
if (this.valueChanged) {
this.valueChanged({ $value: this.value} );
}
};
}
And then here are 2 ways of many to use the expressions, note $value as defined by the component.
<my-comp data-value-changed="$ctrl.someFunction($value)"></my-comp> <br
<my-comp data-value-changed="$ctrl.someProperty = 'Bla: ' + $value"></my-comp>
I tried to set it up to show a variety of things.
The method binding takes an angular expression. I have 2 examples, one calling a function on the parent controller, the other setting a property
This expression is executed with the scope of the parent/caller (ie: has access to parent controller properties, functions etc...)
The component is the one who invokes it by executing the binding name as a function
The component can provide a map of key/value, where the key is a named property that can be used by the caller ($value in my example)
This is a good solution so long as you are OK with the component doing "push" updates to the parent. If for example you only wanted to fetch the data from the component at a specific time (possibly due to time or memory constraints), than there are many other different solutions for that problem.
Hope this helps!
Upvotes: 1
Reputation: 1102
This is a common misunderstanding with Components in Angular. Components should not modify data outside of their own scope. So, if you want to do this, you really should use a Directive.
Here is a quote from the documentation :
Components only control their own View and Data: Components should never modify any data or DOM that is out of their own scope. Normally, in Angular it is possible to modify data anywhere in the application through scope inheritance and watches. This is practical, but can also lead to problems when it is not clear which part of the application is responsible for modifying the data. That is why component directives use an isolate scope, so a whole class of scope manipulation is not possible.
Upvotes: 1