I've had luck building directives that share scope, and ones that isolate scope, but I'm having trouble figuring out the correct way to do both.
<input type="text" ng-model="search" append-me terms="myTerms">
I'm trying to take an input like the one above, and staple a UL that ng-repeats over a list of attributes after it. I have two problems.
1) How do I correctly interface the shared ng-model scope?
2) What am I doing incorrectly with this compile function?
http://jsfiddle.net/vEQ6W/1/
Essentially, you are applying [ngModel] with an input, then automatically modifying a value based on its output. As such, NgModel is definitely an attribute directive.
The ng-model directive binds the value of HTML controls (input, select, text-area) to application data. It is a part of the FormsModule. This directive is used by itself or as part of a larger form. It accepts a domain model as an optional Input.
Angular NgModel is an inbuilt directive that creates a FormControl instance from the domain model and binds it to a form control element. The ngmodel directive binds the value of HTML controls (input, select, textarea) to application data.
Component is used to break up the application into smaller components. But Directive is used to design re-usable components, which is more behavior-oriented. That is why components are widely used in later versions of Angular to make things easy and build a total component-based model.
Mixing isolated scope with ngModel is a documented issue, see the Isolated Scope Pitfall section in the documentation:
Isolated Scope Pitfall Note that if you have a directive with an isolated scope, you cannot require ngModel since the model value will be looked up on the isolated scope rather than the outer scope. When the directive updates the model value, calling ngModel.$setViewValue() the property on the outer scope will not be updated. However you can get around this by using $parent.
Using this knowledge and some freaky scope experiments I've come with two options that does what you want to do:
(1) See this fiddle It makes use of the $parent method as described above.
<div ng-controller="MyCtrl">
<div>
<input ng-form type="text" ng-model="$parent.search" append-me terms="myTerms">
</div>
{{search}}
</div>
myApp.directive('appendMe', ['$compile', function($compile) {
return {
restrict: 'A',
scope: {terms: '='},
link: function(scope, element, attributes) { // linking function
console.log(scope.terms);
var template = '<p>test</p>' +
'<ul><li ng-repeat="term in terms">{{term}}</li></ul>' +
'<p>hm…</p>'
element.after($compile(template)(scope));
}
}
}]);
(2) See this fiddle It does not use $parent, instead it uses the isolated scope to publish the search model as configured via ngModel.
<div ng-controller="MyCtrl">
<div>
<input ng-form type="text" ng-model="search" append-me terms="myTerms">
</div>
{{search}}
</div>
myApp.directive('appendMe', ['$compile', function($compile) {
return {
restrict: 'A',
scope: {terms: '=', search: '=ngModel'},
link: function(scope, element, attributes) { // linking function
console.log(scope.terms);
var template = '<p>test</p>' +
'<ul><li ng-repeat="term in terms">{{term}}</li></ul>' +
'<p>hm…</p>'
element.after($compile(template)(scope));
}
}
}]);
Both options seem to work just fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With