Angular: $ scope. $ Смотреть вложенную коллекцию

0

В моем приложении "Угловое" у меня есть список флажков, который создается через вложенный ng-repeat, например:

<div ng-repeat="type in boundaryPartners">
    <div class="row">
        <div class="col-xs-12 highlight top-pad">
            <div ng-repeat="partner in type.partners" class="highlight">
                <label class="checkbox-inline">
                    <input type="checkbox" value="partner"
                    ng-model="ids[$parent.$index][$index]"
                    ng-true-value="{{partner}}"
                    ng-false-value="{{undefined}}">
                    <p><span ></span>{{partner.name}}<p>
                </label>
            </div>
        </div>
    </div>
</div>

и в моем контроллере:

$scope.ids = [];

$scope.$watchCollection('ids', function(newVal) {
    for (var i = 0, j = newVal.length; i < j; i++) {

        // Create new participatingPatners tier if it doesn't exist
        if(!$scope.report.participatingPartners[i]) $scope.report.participatingPartners[i] = {};

        // Give it an id
        $scope.report.participatingPartners[i].id = i + 1;

        // Map our values to it
        $scope.report.participatingPartners[i].entities = $.map(newVal[i], function(value, index) {
            return [value];
        });
    }

});

Проблема заключается в том, что этот $scope.$watchCollection перестает смотреть, как только я добавил один из всех ids верхнего уровня, поэтому, если я добавлю определенное количество входов из первого вложенного списка, то другой из второго списка, My $scope.report.participatingPartners никогда не обновляется.

Как я могу $watch за изменениями в ids[$parent.$index][$index], чтобы обновить мой объект всякий раз, когда флажок получает билет или неквалифицирован?

  • 0
    Создать демо в плункере . Подозреваемая проблема связана с тем, что ng-model необходимо создавать вложенные массивы, и она может быть лучше в качестве объекта ... или использовать ng-change
  • 1
    Я бы не стал полагаться на значения $index для привязки к другим свойствам модели, подобным этому. $index не представляет никакого материального значения, связанного с элементом, он только представляет индекс, который элемент содержит в этом представлении. Если представление изменяется (элементы добавляются, удаляются, переупорядочиваются и т. Д.), Этот индекс изменяется динамически, в результате чего другие элементы, ссылающиеся на него, внезапно ссылаются на какой-либо другой объект. Вместо этого вы должны организовать свои данные в контроллере или, по крайней мере, предоставить свой собственный уникальный индекс, который ссылается на объект, а не на его представление.
Теги:
watch
ng-repeat

3 ответа

1
Лучший ответ

Вы создаете массив массивов:

$scope.ids = [
  [],
  [],
  //...
]

Но используйте $watchCollection чтобы следить за изменениями внешнего массива, то есть $scope.ids. Это будет определять только изменения, когда вложенные массивы становятся разными объектами (или создаются в первый раз).

Вы можете использовать $scope.$watch("ids", function(){}, true) - с true статусом "глубоких часов", но это было бы очень расточительно, поскольку это дорогостоящая проверка, которая будет выполняться на каждом цикл дайджеста, был ли установлен флажок или нет.

Вместо этого используйте ng-change для запуска обработчика:

<input type="checkbox" value="partner"
       ng-model="ids[$parent.$index][$index]"
       ng-change="handleCheckboxChanged()">
$scope.handleCheckboxChanged = function(){

  // whatever you wanted to do before in the handler of $watchCollection
}
0

$watchCollection похож на $watch поскольку он проверяет ссылку на физический объект, но идет еще на один шаг; он также идет на один уровень глубиной и выполняет контрольную проверку этих свойств.

Вам нужно будет использовать $watch, но установите для параметра objectEquality значение true. Это скажет $watch чтобы выполнить глубокую проверку ссылок. В зависимости от глубины наблюдаемого элемента это может значительно ухудшить производительность.

$watch(watchExpression, listener, [objectEquality]);

-2

Можете ли вы попытаться посмотреть на равенство объектов:

$scope.$watchCollection('ids', function(newVal) {

}, true);
  • 0
    $watchCollection не имеет третьего параметра, который вы определили как «равенство объектов». Вы имели в виду $watch ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню