My dear friends,
We can bind a scope property of a directive to the value of DOM attribute.
This works:
module.directive 'MyDirective', ->
scope:
directiveVar: '='
...
<div class='MyDirective' directive-var='parentVar'></div>
In example above we bind directive's directiveVar
property to parentVar
property of the parent scope.
This is a bi-directional binding, so if directiveVar
is changed parentVar
is automatically updated, and vice versa.
My question is:
Is there a way I can bind a deep child property of my directive's scope instead? Like scope.lv1.directiveVar
or scope.lv1.lv2.lv3.directiveVar
instead of scope.directiveVar
?
What I want to achieve
I have an object in directive scope named lv1
. I want to bind its property directiveVar
to parent property.
This does not work:
scope:
lv1:
directiveVar: '='
And this does not work:
scope:
"lv1.directiveVar": '=myVar'
Demo
This is what works: http://plnkr.co/edit/OClnZ2Cl3BXr60PC2qVP?p=preview
This is what I want to achieve: http://plnkr.co/edit/tQEHeKOzGjGyplCwUtU2?p=preview
I hope this code will help. You can pass in an object and watch its properties or you can nest things in parent/child directives. Either way adding the "=" will enable two way binding on the entire object.
Controller:
$scope.directiveVar = {
level1: {
greeting: 'Hello'
}
};
$scope.otherVar = {
levelA: {
foo: 'bar'
}
};
Markup:
<div data-my-parent-directive data-other-var="otherVar">
<div data-my-directive data-directive-var="directiveVar"></div>
</div>
Directive:
angular.module('MyDirective', [])
.directive('myParentDirective', ['$window',
function ($window) {
return{
restrict: 'AE',
scope:{
otherVar: '='
},
controller: function($scope, $element) {
var othis = this;
this.element = $element;
this.otherVar = $scope.otherVar;
}
};
}
])
.directive('myDirective', ['$window',
function ($window) {
return {
restrict: 'AE',
require: '?myParentDirective',
scope: {
directiveVar: '='
},
link: function(scope, elm, attr, myParentDirectiveCtrl) {
console.log(myParentDirectiveCtrl.otherVar);
console.log(myDirectiveParentCtrl.otherVar.levelA);
scope.$watch('directiveVar.level1', function (newValue, oldValue){
console.log(newValue, oldValue);
});
}
};
}
])
You could simply do this:
<div data-my-parent-directive data-other-var="otherVar">
<div data-my-directive data-directive-var="directiveVar.level1"></div>
</div>
Which is useful when modeling data. For example:
var items = apiService.getItems();
var layers = [...],
$scope.map = {
points: items,
layers: layers,
highAltMap: 'Streets',
lowAltMap: 'Satellite'
};
That said if you are modelling data see this ng-conf video which I believe the speaker touched on some OO patterns.
Edit 2:
You could use a service like this plunker