I'm wondering what's happening behind the scenes when using ng-init
.
Sometimes ng-init
does some unexpected things, and I have a hard time debugging.
Let's say I have the following structure:
<!-- App -->
<div ui-view>
<!-- Component -->
<custom-component>
<!-- Transcluded component -->
<transcluded-component>
<!-- Controller -->
<div ng-controller="MyCtrl">
<!-- Element -->
<div ng-init="myVar = 'hello'">
{{myVar}}
</div>
</div>
</transcluded-component>
</custom-component>
</div>
Which element does myVar
bind to?
Edit 2017-07-21: Added an example
In the following template block (especially within an ng-repeat
), I may use an ng-init
:
<span ng-init="path = getPath()">
<a ng-if="path" ng-href="path">
Click here
</a>
<span ng-if="!path">
Some text
</span>
</span>
In this case, I skipped a function call twice, and kept my template clean.
Sometimes ng-init
does some unexpected things, and I have a hard time debugging.
The ng-init directive evaluates an Angular Expression in the context of the scope of its element. Numerous directives (ng-repeat
, ng-controller
, ng-if
, ng-view
, etc.) create their own scope.
For more information, see
ng-init
Avoid using ng-init
. It tangles the Model and View, making code difficult to understand, debug and maintain. Instead initialize the Model in the controller.
From the Docs:
ngInit
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of
ngInit
, such as for aliasing special properties ofngRepeat
, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather thanngInit
to initialize values on a scope.
Q: I've also added an example of a code block I sometime use.
<!-- Controller --> <div ng-controller="MyCtrl"> <!-- Element --> <div ng-init="myVar = 'hello'"> {{myVar}} </div> </div>
To do the equivalent initialization in the controller:
app.controller("MyVar", function($scope) {
this.$onInit = function() {
$scope.myVar = 'hello';
};
});
By separating concerns of Model and View, the code becomes easier to understand, debug and maintain.