Где я должен разместить $watchers области AngularJS?

Я пытаюсь внести изменения в область AngularJS для запуска действий в модели. Для этого я использую $scope.$watch() в своем контроллере элементов и подключаю эти контроллеры к директивам. Проблема, с которой я сталкиваюсь, заключается в том, что когда элемент появляется на странице более одного раза, я получаю несколько наблюдателей за одним и тем же фрагментом данных.

Например:

angular.module("MyApp", [])
.factory('ItemsModel', function() {
    var item1 = { triggers: 0, catches: 0 };
    var item2 = { triggers: 0, catches: 0 };

    return {
        getItems: function() { 
            return [item1, item2, item1];
        }
    };
})
.controller('AppCtrl', function($scope, ItemsModel) {
    $scope.items = ItemsModel.getItems();    
})
.controller('ItemCtrl', function($scope) {
    $scope.trigger = function() {
        $scope.item.triggers++;
    };    
    $scope.$watch('item.triggers', function(newValue, oldValue) {
        if(newValue != oldValue)
            $scope.item.catches++;
    });
})
.directive('item', function() {
    return {
        scope: {
            item: "="
        },
        controller: 'ItemCtrl'
    };
});

Здесь item1 появляется дважды в массиве items, поэтому я получаю два контроллера, наблюдающих за одним и тем же фрагментом данных. Если бы triggers были изменениями в свойстве, а catches были сохранены обратно на сервер, то я бы сохранял каждое изменение в item1 дважды. Если элемент появился три раза, он сохранится три раза.

Я чувствую, что прослушиватель изменений должен войти в модель, но модели не имеют доступа к области. Повторение каждого элемента и добавление поведения в AppCtrl не имеет для меня большого смысла. Так куда деваться наблюдателям?

Я также поместил это в скрипку здесь: http://jsfiddle.net/nicholasstephan/p56MT/3/

Спасибо


person nicholas    schedule 17.04.2013    source источник
comment
Директива должна использоваться для повторно используемых компонентов. Это не оболочка для контроллера. И аргумент контроллера для директивы и ng-контроллер - это две разные вещи. Они не одно и то же.   -  person ganaraj    schedule 17.04.2013
comment
@ganarj Хорошо. Если я возьму пустую директиву и просто использую ng-controller, контроллер все равно будет вызываться дважды для одного и того же фрагмента данных. jsfiddle.net/vFtbL/1 Вопрос в том, куда это $scope.$watch('item.triggers'... должно идти?   -  person nicholas    schedule 17.04.2013
comment
Не могли бы вы объяснить сценарий реального мира, который вы пытаетесь решить? Это слишком абстрактно.   -  person ganaraj    schedule 17.04.2013
comment
Ничего действительно. Например, этот пост представляет собой объект со свойствами: тема, тело, комментарии, теги и т. д. Я хотел бы отслеживать изменения в массиве тегов и запускать сохранение на сервере при добавлении или удалении тега.   -  person nicholas    schedule 17.04.2013


Ответы (1)


Я не использовал контроллер, указанный в директиве, как у вас здесь, но альтернативный способ — просто настроить часы в директиве элемента. Таким образом, часы сработают только один раз при изменении элемента в директиве.

person BoxerBucks    schedule 15.05.2013