We have next directive implemented:
angular.module('app', [])
.directive('dIsolatedWorks', function() {
return {
scope: {
prop: '='
},
template: '<span>{{name}}: {{prop}}</span>',
link: function(scope) {
scope.name = 'isolated';
scope.prop = 'link';
}
};
})
.directive('dIsolated', function() {
return {
scope: {
prop: '@'
},
template: '<span>{{name}}: {{prop}}</span>',
controller: function($scope) {
$scope.prop = 'controller';
},
link: function(scope) {
scope.name = 'isolated';
scope.prop = 'link';
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div d-isolated-works prop="attribute"></div>
<div d-isolated prop="attribute"></div>
</div>
Actually during implementation I was sure that assignment to the scope.prop
field will change the variable and it will be displayed as 'link'
, not 'attribute'
.
But currently we see that the real value will be isolated: attribute
.
However it can be simply fixed by changing string assignment to object assignment.
Can you explain such behavior?
So after investigating angularjs code for an answer I have found the correct one - according to angular.js v1.3.20
we have next lines of code in linking function for the @
attributes (line 7698):
case '@':
attrs.$observe(attrName, function(value) {
isolateBindingContext[scopeName] = value;
});
attrs.$$observers[attrName].$$scope = scope;
if (attrs[attrName]) {
// If the attribute has been provided then we trigger an interpolation to ensure
// the value is there for use in the link fn
isolateBindingContext[scopeName] = $interpolate(attrs[attrName])(scope);
}
break;
According to this code
As a result we can say that usage of string binded params in the directive body is allowed only as a readonly value until it is wrapped into the timeout block (or any other with delayed execution)