Reputation: 4957
I'm attempting to create a reusable parent container directive. What I want is something like the following:
<parent title="Parent title">
<child></child>
</parent>
where I can have the child elements change a value in the parent's scope.
I've attempted this binding as follows (see this fiddle):
myApp.directive('parent', function() {
return {
scope: {'title': '@'},
transclude: true,
// Manually transclude so we set parent scope to be this scope.
link: function(scope, element, attrs, ctrl, transclude) {
transclude(scope.$new(), function(content) {
element.append(content);
});
},
restrict: 'EA',
template: '<div><b>PARENT:</b> {{title}}</div>',
controller: function($scope) {
$scope.inherited = true;
$scope.$watch('inherited', function(newValue, oldValue) {
if(!newValue) {
console.log('Parent: inherited switched');
}
});
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
scope:{
inherited: '='
},
template: '<div><b>Child:</b> inherited attribute = {{inherited}}</div>',
controller: function($scope) {
// Why is inherited not bound to parent here?
console.log($scope.inherited);
// It obviously exists in the parent...
console.log($scope.$parent.inherited);
}
}
});
From my understanding of the API, setting an object hash scope with inherited: '='
should bind to the parent property, but as you can see in the fiddle, it doesn't.
I have two questions:
inherited
not bound to the parent property?Caveats:
require: '^parent'
, since this creates a rather strong dependency of the child on the parent (I might want to create a number of possible parent containers and a number of child directives and mix-and-match).link
in the child directive to climb to the $parent
. That's a hack and won't work in general for deeply nested directives.Thanks for any guidance.
Upvotes: 0
Views: 171
Reputation: 64657
You can either do:
<child inherited="inherited"></child>
where you actually pass in the inherited attribute, since that is what it is looking for when you do
scope:{
inherited: '='
},
Or you could do:
myApp.directive('child', function() {
return {
restrict: 'EA',
scope: false,
so that it uses it's parent's scope.
Either way, you are likely to run into some issues binding to a primitive. You will probably save yourself a lot of headache by making inherited an object, passing the object around, and when you need to display it show the object property:
JS:
$scope.inherited = {is: true};
HTML:
{{inherited.is}}
But then keep passing around the whole object.
Upvotes: 1