According to this Plunkr, using ng-init
in a directive won't execute a function assigned to scope inside link, but it will if I do it in controller.
Can anyone explain this?
app.js
var app = angular.module('app', []);
app.directive('linkDir', function(){
return {
restrict: 'E',
scope: true,
template: 'Link: <p ng-init="initLink()">{{ linkmsg }}</p>',
link: function(scope){
scope.initLink = function(){
scope.linkmsg = 'link function executed'
}
}
};
});
app.directive('controllerDir', function(){
return {
restrict: 'E',
scope: true,
template: 'Controller: <p ng-init="initController()">{{ controllermsg }}</p>',
controller: function($scope){
$scope.initController = function(){
$scope.controllermsg = 'controller function executed';
}
}
};
});
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app">
<link-dir></link-dir>
<controller-dir></controller-dir>
</body>
</html>
This has to due with how Angular's directives work. The linkage between the scope
and the DOM element is a little bit complex to explain, but making a long story short, if you use controllers, the scope
will be immediately created with the initController
property, while if you use the link
attribute, the scope will only be populated after it as been linked to the DOM element (this means initLink
will be undefined during the ng-init
).
In order to avoid these problems, don't use the ngInit
directive, as stated on Angular's documentation:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Stick with Controllers if you need to init properties on the scope
.