html:
<!doctype html>
<html>
<head>
</head>
<body>
<div ng-app="project">
<div ng-controller="mainCtrl">
{{ property1 }}
<br />
{{ property2 }}
<div class="ts" d-child property1="{{ property1 }}cloud" property2="property2">
property1: {{ property1 }}
<br />
property2: {{ property2 }}
</div>
</div>
</div>
</body>
</html>
js:
angular.module('project', [])
.controller('mainCtrl', function($scope) {
$scope.property1 = 'ss';
$scope.property2 = 'dd';
});
angular.module('project')
.directive('dChild', function() {
return {
restrict: 'A',
scope: {
property1: '@',
property2: '='
},
link: function(scope, element, attrs) {
}
// template: '<input type="text" ng-model="property1" />'
}
})
I thought the property1: {{ property1 }}
would be "property1: sscloud",but it turns out to be "ss",as if it still refers to the scope of the mainCtrl
controller, shouldn't it be refer the scope of the d-child
directive?
if I use template in the directive,it does refer to the right scope and shows 'sscloud',anyone can tell me why?
When angular compiles an element with isolated scope it has some rules:
- If directives has no template property (or templateUrl), the inner content is attached to the parent scope. Actually before this commit, inner contents were getting the isolated scope. check your example to confirm it works on versions less than 1.2
- If directives do have a template property then it would override the inner content (unless trancluded).
- Only when you use a transclusion, then the inner content is attached to a sibling scope (non isolated).
- The reason why angular works this way is to let reusable components be loosely coupled, and not have any side effects on your application.
- Directives without isolate scope do not get the isolate scope from an isolate directive on the same element (see important commit).
- Directive's template gets the isolated scope anyways.
If you want to alter this behavior you can pass the isolated scope to the tranclusion function like so:
angular.module('project')
.directive('dChild', function() {
return {
restrict: 'A',
transclude: true,
scope: {
property1: '@',
property2: '='
},
link: function(scope, element, attrs, ctrl, linker) {
linker(scope, function(clone, scope){
element.append(clone)
})
}
}
})
I highly recommend you to see these tutorials:
- Angular.js - Transclusion basics
- Angular.js - Components and containers
And to read more:
- Access directive's isolate scope from within transcluded content
- https://github.com/angular/angular.js/wiki/Understanding-Scopes
I'm not quite sure about this, I'm pretty sure it all has to do with when each {{}} is evaluated, and when the scope of the directive becomes isolated. My suggestion is to place the content in a template, as it seems to be working when doing so.
If you want to read more about the difference of of "@" and "=" in directive scopes, here's the best text I've found about it.
What is the difference between '@' and '=' in directive scope in AngularJS?
I think you have to use the transclude
option
.
In fact, as AngularJS
docs says :
What does this transclude option do, exactly? transclude makes the contents of
a directive with this option have access to the scope outside of the directive
rather than inside.
Because of the Directives
isolated scope
that you created
More docs at:
http://docs.angularjs.org/guide/directive