16

What is the scope of ng-init in Angular? Here's a simple example that demonstrates my question:

<div ng-init="model = { year: '2013'}">
    <a href="" ng-click="model.year = '2012'">2012</a> |
    <a href="" ng-click="model.year = '2013'">2013</a>
    <div>Showing {{ model.year }}</div>
    <hr />
</div>
<div ng-init="model = { year: '2013'}">
    <a href="" ng-click="model.year = '2012'">2012</a> |
    <a href="" ng-click="model.year = '2013'">2013</a>
    <div>Showing {{ model.year }}</div>
</div>

Live example available here: http://plnkr.co/edit/HkioewOzzglvFMKDPdIf?p=preview

Is seems that ng-init scope is shared among the 2 div[ng-init]. For example, if you click on the year '2012' in either section, it changes the year property in both sections.

Is there a way to tell angular to create a new scope for each ng-init and thereby clicking the '2012' year will only impact the section that it belongs to?

ruffin
  • 16,507
  • 9
  • 88
  • 138
Johnny Oshika
  • 54,741
  • 40
  • 181
  • 275

3 Answers3

20

ng-init does not create a new scope, it evaluates an expression in the current scope. In your example, both your ng-init are in the same scope, changing the same model property will affect the other. If you need separate scope, you could try ng-controller.

<div ng-controller="MainCtrl" ng-init="model = { year: '2013'}">
      <a href="" ng-click="model.year = '2012'">2012</a> |  <a href="" ng-click="model.year = '2013'">2013</a>
      <div>Showing {{ model.year }}</div>
      <hr />
    </div>
<div ng-controller="MainCtrl" ng-init="model = { year: '2013'}">
      <a href="" ng-click="model.year = '2012'">2012</a> |  <a href="" ng-click="model.year = '2013'">2013</a>
      <div>Showing {{ model.year }}</div>
 </div>

DEMO

Side notes: In this case, you don't need ngInit, just initialize the value directly in your controller.

The only appropriate use of ngInit is for aliasing special properties of ngRepeat. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.

https://docs.angularjs.org/api/ng/directive/ngInit

Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • 2
    But then, if you're using `ng-controller`, `ng-init` becomes useless. Or at least confusing. Better to put the initialization code inside the controller. – 7hi4g0 Oct 04 '14 at 21:31
  • @7hi4g0: I agree. But I think it's not much related to this question. This question is about scope of ng-init. – Khanh TO Oct 05 '14 at 03:47
  • 1
    Still I think is better to put some kind of warning on the answer since angularjs' docs itself states that `ng-if` only makes sense together with `ng-repeat` – 7hi4g0 Oct 05 '14 at 07:31
  • @7hi4g0: When you are using ng-repeat in your page and the list you are iterating on is resault of an ajax request, you **have** to use ng-init. – RezKesh Dec 04 '14 at 12:31
  • @7hi4g0 Of course you don't. Make your ajax call, update your model, and your ng-repeat will act appropriately. – Gargoyle Mar 21 '15 at 20:57
  • The angular docs have been updated to include one other valid usage of ng-init, namely server-side includes: "There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting." – Adam Wise Aug 07 '17 at 16:26
3

Since ng-if creates a new scope, you can accomplish it just by:

<div ng-if="true" ng-init="model = { year: '2013'}">
Max Flex
  • 1,116
  • 10
  • 16
0

Hello to clarify and find the solution, could you please try out the solution given below

<script>
    var app = angular.module('myAngularApp', []);
    app.controller('myCtrl1', function ($scope) { });
    app.controller('myCtrl2', function ($scope) { });
</script>

<body ng-app="myAngularApp">
    <div ng-controller="myCtrl1" ng-init="model = { year: '2012'}">
        <a href="" ng-click="model.year = '2012'">2012</a> | <a href="" ng-click="model.year = '2013'">2013</a>
        <div>Showing {{ model.year }}</div>        
    </div>
    <hr />
    <div ng-controller="myCtrl2" ng-init="model = { year: '2013'}">
        <a href="" ng-click="model.year = '2012'">2012</a> | <a href="" ng-click="model.year = '2013'">2013</a>
        <div>Showing {{ model.year }}</div>
    </div>
</body>
Midhun m k
  • 66
  • 3