Reputation: 675
I am a little confused about when 'template' in AngularJS directive is rendered. See following code snippets:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js" data-semver="1.1.5"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<example-directive name="{{name}}"></example-directive>
</body>
</html>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'First ONE ';
});
app.directive('exampleDirective', function() {
return {
restrict: 'E',
scope: {
name: "@"
},
template: '<p>Hello {{name}}!</p>',
controller: function($scope, $element){
$scope.name = $scope.name + "Second ";
$scope.name2 = $scope.name + "Second ";
},
link: function(scope, el, attr) {
scope.name = scope.name + "Third ";
$scope.name2 = $scope.name + "Second ";
}
}
})
It displays "Hello First One" which means none of the first statement in controller and link functions changes the value of name in scope or the change is not reflected in the template.
However, if I changed the directive to
template: '<p>Hello {{name2}}!</p>'
or change 'name' to two way binding by using '=' instead of '@'
it renders "Hello First ONE Second Second !" as expected.
The plunker is here
So does it mean for one way binding, scope var in template is rendered before controller and link functions kick in?
Upvotes: 2
Views: 198
Reputation: 2481
Just change this:
<example-directive name="{{name}}"></example-directive>
to this:
<example-directive name="name"></example-directive>
and this:
scope: {
name: "@"
},
to this:
scope: {
name: "="
},
And it will work.
sorry, for not reading the whole question. here's what's in the docs:
@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).
notice the last part: The name is read from the parent scope (not component scope)
Upvotes: 1