在ng-repeat循环内操作来自子控制器的父控制器数组

时间:2014-09-12 01:26:37

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

我想操纵存储在父控制器中的数组中的项目。当我操作项目时,我想在子控制器内部的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>

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

html变为:

<button ng-click='cc.change_item_name(pc.myarray,$index)'>change item name</button>

答案 2 :(得分:0)

将数据源从父控制器移动到服务并将该服务注入到两个控制器中允许它们访问相同的数据。 [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>