В моем приложении "Угловое" у меня есть список флажков, который создается через вложенный 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]
, чтобы обновить мой объект всякий раз, когда флажок получает билет или неквалифицирован?
Вы создаете массив массивов:
$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
}
$watchCollection
похож на $watch
поскольку он проверяет ссылку на физический объект, но идет еще на один шаг; он также идет на один уровень глубиной и выполняет контрольную проверку этих свойств.
Вам нужно будет использовать $watch
, но установите для параметра objectEquality значение true. Это скажет $watch
чтобы выполнить глубокую проверку ссылок. В зависимости от глубины наблюдаемого элемента это может значительно ухудшить производительность.
$watch(watchExpression, listener, [objectEquality]);
Можете ли вы попытаться посмотреть на равенство объектов:
$scope.$watchCollection('ids', function(newVal) {
}, true);
$watchCollection
не имеет третьего параметра, который вы определили как «равенство объектов». Вы имели в виду $watch
?
ng-model
необходимо создавать вложенные массивы, и она может быть лучше в качестве объекта ... или использоватьng-change
$index
для привязки к другим свойствам модели, подобным этому.$index
не представляет никакого материального значения, связанного с элементом, он только представляет индекс, который элемент содержит в этом представлении. Если представление изменяется (элементы добавляются, удаляются, переупорядочиваются и т. Д.), Этот индекс изменяется динамически, в результате чего другие элементы, ссылающиеся на него, внезапно ссылаются на какой-либо другой объект. Вместо этого вы должны организовать свои данные в контроллере или, по крайней мере, предоставить свой собственный уникальный индекс, который ссылается на объект, а не на его представление.