如何获取一个大对象,使用其中的子对象作为同一控制器的多个实例的数据,并使它们保持同步?

时间:2014-09-19 07:13:16

标签: javascript angularjs scope angularjs-scope

对问题含糊不清的道歉:-P

我有一个包含我所有数据的JavaScript对象。我有一个控制器,我将在整个应用程序中多次使用。因此,控制器都在处理相同的数据,使用服务将数据添加到应用程序中。

为了支持只读/编辑模式交互,我在服务中制作了原始数据源的两个副本。当用户操纵数据时,他们正在操纵编辑模式数据源。然后,他们可以按一个按钮将数据保存到编辑模式数据源到只读模式数据源(使用angular.copy)。

我还希望控制器的实例只能处理数据源的一部分而不是整个数据源。

我看到的行为是angularjs能够更新部件,使它们保持同步;但是当我按下按钮来执行angular.copy时,似乎重新分配变量而不是调整它所指向的值。

以下代码,这里是jsfiddle http://jsfiddle.net/q5ca5quq/1/

<html ng-app='app'>
<body>

    <div ng-controller='a_controller as ctrl_1'>
        read_mode_inner = {{ ctrl_1.read_mode_inner }}<br>
        edit_mode_inner = {{ ctrl_1.edit_mode_inner }}<br>
        <br>
        <input ng-model='ctrl_1.edit_mode_inner[0].a'>
    </div>    
    <br><br><br>
    <div ng-controller='a_controller as ctrl_2'>
        read_mode_inner = {{ ctrl_2.read_mode_inner }}<br>
        edit_mode_inner = {{ ctrl_2.edit_mode_inner }}<br>
        <br>
        Change this and press button below <input ng-model='ctrl_2.edit_mode_inner[0].a'> <br>
        <button ng-click='ctrl_2.change()'>Copy edit_mode_inner into read_mode_inner</button>
    </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 = {
            xx : [{'a':1}, {'b':2}, {'c':3}],
            yy : [{'a':1}, {'b':2}, {'c':3}]
        }

        return {
            read_mode : data,
            edit_mode : angular.copy(data)
        }
    }])
    .controller('a_controller', ['DataService', function(DataService) {
        var self = this;
        window.s = self; // For debugging

        self.read_mode = DataService.read_mode;
        self.edit_mode = DataService.edit_mode;

        self.read_mode_inner = self.read_mode.xx;
        self.edit_mode_inner = self.edit_mode.xx;

        self.change = function(){
            self.read_mode_inner = angular.copy(self.edit_mode_inner);
        }

    }]);


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

1 个答案:

答案 0 :(得分:0)

http://jsfiddle.net/q5ca5quq/2/

您可以使用服务在控制器之间共享数据,但如果您希望每次更改服务中的值时更新所有控制器实例,您需要在控制器内部使用$ watch:

$scope.change = function(){
    DataService.read_mode.xx = angular.copy($scope.edit_mode_inner);
}

$scope.$watch(function(){return DataService}, function(dataService){
    $scope.read_mode_inner = dataService.read_mode.xx;
}, true);

为此,您需要使用angular $ scope而不是this / self reference。注意在HTML中使用$ scope还简化了角度表示法。您无需单独命名控制器:

而不是:

<div ng-controller='a_controller as ctrl_1'>
    read_mode_inner = {{ ctrl_1.read_mode_inner }}<br>
    edit_mode_inner = {{ ctrl_1.edit_mode_inner }}<br>
</div>

你只需要:

<div ng-controller='a_controller'>
    read_mode_inner = {{ read_mode_inner }}<br>
    edit_mode_inner = {{ edit_mode_inner }}<br>
</div>

因为$ scope负责其余部分。