【问题标题】:AngularJS Controller Inheritance and Order of ExecutionAngularJS 控制器继承和执行顺序
【发布时间】:2015-07-14 09:52:31
【问题描述】:

我在 Angular 中使用父/子控制器继承,遇到了一些我不理解的行为。

基本上,我在父控制器中为对象设置属性,并在子控制器中将其设置为不同的值。我输出在父控制器中设置的值之前子控制器中的代码应该运行。但是,我看到子控制器代码已经运行并设置了值。

Parent.Controller.js

testapp.controller('ParentController', function($scope) {
  $scope.init = function() {
    $scope.myValue = 'Primitive value, defined in ParentController';
    $scope.myObject = {
      value: "Object property value, defined in ParentController"
    }
  } 

  $scope.init();
});

Child.Controller.js

testapp.controller('ChildController', function($scope) {
    $scope.init = function() {
    $scope.myValue = 'Primitive value, set in ChildController';
    $scope.myObject.value = "Object property value, set in ChildController";
  } 

  $scope.init();
});

HTML 模板

<div ng-controller="ParentController" class="outer">
  1. Primitive value on scope: <span style="font-weight:bold">{{myValue}}</span>
  <br/>2. Object value on scope: <span style="font-weight:bold">{{myObject.value}}</span>
  <p>
    <div ng-controller="ChildController" class="inner">
      3. Primitive value on scope: <span style="font-weight:bold">{{myValue}}</span>
      <br/>4. Object value on scope: <span style="font-weight:bold">{{myObject.value}}</span>
    </div>
  <p>
  5. Primitive value on scope: <span style="font-weight:bold">{{myValue}}</span>
  <br/>6. Object value on scope: <span style="font-weight:bold">{{myObject.value}}</span>      
</div>

我本来希望 #2 显示由父控制器定义的对象的值,因为子控制器应该还没有执行(子控制器的 ng-controller 指令在此以南几行) .

这是Plunk

如果有人能帮助我理解这种行为,我将不胜感激。

谢谢,

菲利普

【问题讨论】:

    标签: javascript angularjs inheritance


    【解决方案1】:

    与执行顺序无关,与原型继承有关。

    基元没有继承,但对象有。

    原始示例

    var a="foo";
    var b = a; //"foo"
    a="some value"
    alert(b) // is still "foo"
    

    b 被赋值为 a 仅在赋值时所具有的值

    对象示例

    var a={x:'foo'};
    var b = a; //  {x:'foo'}
    a.x="a new value";
    alert(b.x) // also changed to "a new value" 
    

    ab 是对同一个对象的引用

    您看到的是原语没有绑定到父级,但对象确实......正如预期的那样。

    子作用域原语将根据它们被分配的那一刻从父级分配值。之后对任一变量的更改将独立于源或子

    对象仍然是引用,对任何单个引用的任何地方所做的更改都将反映在所有引用中

    【讨论】:

      【解决方案2】:

      当稍后更改值时,动态绑定也会更改变量的首次显示。

      由于子作用域中没有定义myObject,所以父作用域中的myObject被改变了。

      【讨论】:

        【解决方案3】:

        无论何时执行哪个控制器都没有关系:因为作用域是在两个控制器之间继承的,所以myObject 变量也是如此。

        因此,当子控制器更新myObject.value 时,它使用相同 myObject 而不是其父控制器,因此您在 HTML 中的两个位置看到相同的值。

        这是意料之中的,也是经常想要的。如果您不希望子控制器影响其父控制器,则应在该子控制器上定义一个新对象:

        testapp.controller('ChildController', function($scope) {
          $scope.init = function() {
            $scope.myValue = 'Primitive value, set in ChildController';
            $scope.myChildObject =  {value: "Object property value, set in ChildController"};
          } 
        });
        

        PS:如果你在父子init函数中都添加console.log,你会看到父控制器确实在子控制器之前被读取。

        【讨论】:

          猜你喜欢
          • 2013-03-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-27
          • 2020-06-24
          • 1970-01-01
          • 2014-10-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多