I found quite a strange behaviour of scope:true type for inner content of a directive:
<body ng-init="x=10">
<mydir>
{{x}}
</mydir>
</body>
so {{x}} is inner content, and directive definition is:
.directive('mydir', function() {
return {
scope: {},
link: function(scope){
scope.x = 5;
}
};
});
When we define scope as isolated (scope:{}), it outputs {{x}} as 10, so uses outer scope. But when we create new scope for the directive(scope:true), it will use it for inner content and output 5. So it uses different scopes for inner content for 2 cases. Could somebody give me a hint/link to souce code/manual for the explanation for this inconsistency?
Here is plnk to play with the code.
UPD: I understand what is JavaScript prototype inheritance. I know the difference between directive scope types. And my aim is not to display 5 instead of 10. The question is about inner template that in both cases should be interpolated with parent scope, which does not have access to properties of child/isolated one.
In your original code snippet, the {{x}}
does not belong to <mydir>
. You should define a template to the directive.
// js
.directive('mydir', function() {
return {
template: '{{x}}',
scope: {},
link: function(scope){
scope.x = 5;
}
};
});
// html
<body ng-init="x=10">
<mydir></mydir>
</body>
Here is the preview
A got the answer from angular issues: https://github.com/angular/angular.js/issues/13845#issuecomment-174953398
And here is source code answer: https://github.com/angular/angular.js/blob/eae0a1121ffcc636d760463105dcdc548ea47390/src/ng/compile.js#L2538-L2545
var scopeToChild = scope;
if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
scopeToChild = isolateScope;
}
childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
resume: In case of isolated scope type, scope is provided ONLY for directive template, but not for inner content.
Something not right is going on. If you run your code in Chrome with Batarang turned on, you can see when scope : {} that it is indeed creating a new scope separate from the first, completely disconnected, and setting the variable to 5. But your interpolated string is binding to outer scope. If you set scope : true it is also create a new scope inherited from the outer, and the {{x}} interpolation is binding correctly. I don't think it is scope parameter on the directive that is not working, something with binding is not working.
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