这是保持两个控制器之间数据同步的好方法吗?

时间:2013-06-21 22:18:11

标签: javascript angularjs

我有一个同时具有两个控制器的页面布局,一个根据存储在浏览器本地存储中的数据和至少一个其他控制器(显示绑定到路径和数据),将数据显示为侧导航类型。图。

我在下面创建了这个小线框图形,显示了页面布局:

Example image two controllers

第二个控制器用于操作本地存储的数据,并执行添加新项目或删除现有项目等操作。我的目标是保持数据同步,如果项目被“ManageListCrtl”添加或删除,则使用“ListCtrl”的侧面导航应立即更新。

我通过将本地存储逻辑分离为一个服务来存档它,该服务在操作列表时执行广播,每个控制器监听此事件并更新范围列表。

这很好用,但我不确定是否有最佳做法。

以下是我的代码的精简版本,其中只包含必要的部分:

angular.module('StoredListExample', ['LocalObjectStorage'])
    .service('StoredList', function ($rootScope, LocalObjectStorage) {
        this.add = function (url, title) {
            // local storage add logic

            $rootScope.$broadcast('StoredList', list);
        };

        this.delete = function (id) {
            // local storage delete logic

            $rootScope.$broadcast('StoredList', list);
        };

        this.get = function () {
            // local storage get logic
        };
    });

angular.module('StoredListExample')
    .controller('ListCtrl', function ($scope, StoredList) {
        $scope.list = StoredList.get();

        $scope.$on('StoredList', function (event, data) {
            $scope.list = data;
        });
    });

angular.module('StoredListExample')
    .controller('ManageListCtrl', function ($scope, $location, StoredList) {
        $scope.list = StoredList.get();

        $scope.add = function () {
            StoredList.add($scope.url, $scope.title);
            $location.path('/manage');
        };

        $scope.delete = function (id) {
            StoredList.delete(id);
        };

        $scope.$on('StoredList', function (event, data) {
            $scope.list = data;
        });
    });

2 个答案:

答案 0 :(得分:2)

我没有看到这样做的任何错误。你的另一个选择当然就是用$ rootScope将$ rootScope注入到控制器和pub / sub之间。$ broadcast和$ rootScope。$ on。

angular.module('StoredListExample')
.controller('ListCtrl', function ($scope, $rootScope) {
    $scope.list = [];

    $rootScope.$on('StoredList', function (event, data) {
        $scope.list = data;
    });
});

angular.module('StoredListExample')
.controller('ManageListCtrl', function ($scope, $rootScope, $location) {
    $scope.list = [];

    $scope.add = function () {
        //psuedo, not sure if this is what you'd be doing...
        $scope.list.push({ url: $scope.url, title: $scope.title});
        $scope.storedListUpdated();
        $location.path('/manage');
    };

    $scope.delete = function (id) {
        var index = $scope.list.indexOf(id);
        $scope.list.splice(index, 1);
        $scope.storedListUpdated();
    };

    $scope.storedListUpdated = function () {
        $rootScope.$broadcast('StoredList', $scope.list);
    };
});

此外,您可以通过使用通用父控制器以杂乱但有趣的方式实现此目的。因此,你会从'ManageListCtrl'向父控制器发出'StoredListUpdated'事件,然后父控制器会将同一事件广播到'ListCtrl'。这样可以避免使用$ rootScope,但是当你以这种方式添加更多事件时,它在可读性方面会变得非常混乱。

答案 1 :(得分:1)

使用作为单例的公共服务在两个控制器之间共享数据总是更好的做法 - 只需确保仅使用引用而不是在其中一个控制器中创建本地对象服务