【问题标题】:Manipulate array of parent controller from child controller inside ng-repeat loop从 ng-repeat 循环中的子控制器操作父控制器数组
【发布时间】:2014-09-12 01:26:36
【问题描述】:

我想操作存储在父控制器中的数组中的项目。当我操作这些项目时,我想从子控制器内的 ng-repeat 循环中执行此操作。

据我所知,父控制器中的数组正在更新——实际上是s===cs。我已经读到$scope.$apply() 可能是答案,但我不确定如何使用下面的“controller as”语法来调用它——或者这是否明智。

<html ng-app='app'>
<body ng-controller='parent_controller as pc'>
    {{ pc.parent_name }}
    <br>
    Enter parent_name <input ng-model='pc.parent_name'/>
    <br>
    <button ng-click='pc.change_parent_name()'>change parent_name</button>

    <div ng-controller='child_controller as cc'>
        <div ng-repeat='item in pc.myarray' style='border:1px solid #ccc; margin:20px;'>
            Item = {{ item }}
            <br>
            <button ng-click='cc.change_item_name($index)'>change item name</button>
        </div>
    </div>

<script src="js/jquery.min.js"></script>
<script src="js/angular.min.js"></script>
<script type='text/javascript'>

var app = angular.module('app',[]);

function parent_controller(){
    var self = this;
    window.s = self; // For debugging

    self.myarray = ['a','b','c'];

    self.change_parent_name = function () {
        self.parent_name = 'changed!!';
    }
}
app.controller('parent_controller',[parent_controller]);

function child_controller() {
    var self = this;    
    window.cs = self; // For debugging

    parent_controller.apply(self, arguments);

    self.change_item_name = function(index){
        console.log(index);
        self.myarray[index] = 'changed';
    }

}
app.controller('child_controller',[child_controller]);

</script>
</body>
</html>

【问题讨论】:

    标签: angularjs angularjs-scope angularjs-ng-repeat


    【解决方案1】:

    由于数组具有原始字符串类型,将父数组和索引传入子控制器函数,它应该可以正常工作。

     self.change_item_name = function(items, index){
            console.log(index);
            items[index] = 'changed';
        }
    

    而 html 变为:

    &lt;button ng-click='cc.change_item_name(pc.myarray,$index)'&gt;change item name&lt;/button&gt;

    【讨论】:

    • 啊,该死的。我简化了我的例子,忘记了参考与价值。进行您提到的更改允许一个按钮更改项目名称,但按其他按钮会出现错误:[ngRepeat:dupes]。你知道它为什么会这样做吗?我还尝试将 myarray 更改为保存对象而不是字符串(这是我更感兴趣的),但它根本不起作用(虽然没有重复错误:-P)
    • 出现 dup 错误是因为 ng-repeat 需要唯一标识元素,对于对象,它通过向它们添加键来实现。
    • 如果你使用对象,那么它应该可以工作。您如何使用基于对象的方法。
    • 啊,是的,当然。 self.myarray = [ {'a':1}, {'b':2}, {'c':3} ]; ....and..... self.change_item_name = function(index){ console.log(index); self.myarray[index] = {'changed': 999}; }
    • myarray 据我了解是在父控制器上定义的,因此您无法从子控制器中获取它。试试function(array,index) { array[index]={...};
    【解决方案2】:

    最好将子控制器放在 ng-repeat 上,然后使用它来更新父控制器。 $scope.$apply 不是必需的。如果要从控制器代码更新父控制器,最好使用服务在两者之间进行通信。

    【讨论】:

      【解决方案3】:

      将数据源从父控制器移动到服务并将该服务注入两个控制器允许它们访问相同的数据。 [AngularJS API reference]

      此示例执行此操作并添加了第三个控制器,以突出显示数据在控制器之间共享的程度。

      下面的

      ctrl_3 还显示了如何使用 controller as 语法访问 $scope。 $scope 仅用于 console.log 部分 - 它不用于此服务方法。

      <html ng-app='app'>
      <body ng-controller='a_controller as ctrl_1'>
          {{ ctrl_1.parent_name }}
          <br>
          Enter parent_name <input ng-model='ctrl_1.parent_name'/>
          <br>
          <button ng-click='ctrl_1.change_parent_name()'>change parent_name</button>
      
          <div><strong>ctrl_2</strong></div>
          <div ng-controller='a_controller as ctrl_2'>
              <div ng-repeat='item in ctrl_2.myarray' style='border:1px solid #ccc; margin:20px;'>
                  Item = {{ item }}
                  <br>
                  <button ng-click='ctrl_2.change_item_name(ctrl_2.myarray, $index)'>change item name</button>
              </div>
          </div>
      
          <!-- an extra repeat of the myarray, this time using ctrl_1 for the repeat of myarray but ctrl_3 as the controller, just to show it all ties back to the same data source -->
          <hr>
          <div><strong>ctrl_3</strong></div>
          <div ng-controller='a_controller as ctrl_3'>
              <div ng-repeat='item in ctrl_1.myarray' style='border:1px solid #ccc; margin:20px;'>
                  Item = {{ item }}
                  <br>
                  <button ng-click='ctrl_3.change_item_name(ctrl_3.myarray, $index)'>change item name</button>
              </div>
          </div>
      
      
      <script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js'></script>
      <script type='text/javascript'>
      
      angular.module('app',[])
      .factory('DataService', [function() {
          data = [ {'a':1}, {'b':2}, {'c':3} ];
      
          return {
              myarray : data
          }
      }])
      .controller('a_controller', ['DataService', '$scope', function(DataService, $scope) {
          var self = this;
          window.s = self; // For debugging
          console.log($scope);
      
          self.myarray = DataService.myarray;
      
          self.change_parent_name = function () {
              self.parent_name = 'changed!!';
          }
      
          self.change_item_name = function(array,index){ 
              array[index] = {'changed': 999}; 
          }
      }]);
      
      
      </script>
      </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 2016-05-20
        • 2016-02-02
        • 1970-01-01
        • 2017-10-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多