Проблема
У меня есть поле со списком, в основном элемент select
, который заполняется массивом сложных объектов ng-options
. Когда я обновляю любой объект коллекции на уровне второго уровня, это изменение не применяется к полем со списком.
Это также задокументировано на веб-сайте AngularJS:
Обратите внимание, что
$watchCollection
выполняет мелкое сравнение свойств объекта (или элементов в коллекции, если модель представляет собой массив). Это означает, что изменение свойства глубже первого уровня внутри объекта/коллекции не приведет к повторному рендерингу.
Angular вид
<div ng-app="testApp">
<div ng-controller="Ctrl">
<select ng-model="selectedOption"
ng-options="(selectedOption.id + ' - ' + selectedOption.name) for selectedOption in myCollection track by selectedOption.id">
</select>
<button ng-click="changeFirstLevel()">Change first level</button>
<button ng-click="changeSecondLevel()">Change second level</button>
<p>Collection: {{ myCollection }}</p>
<p>Selected: {{ selectedOption }}</p>
</div>
</div>
Angular контроллер
var testApp = angular.module('testApp', []);
testApp.controller('Ctrl', ['$scope', function ($scope) {
$scope.myCollection = [
{
id: '1',
name: 'name1',
nested: {
value: 'nested1'
}
}
];
$scope.changeFirstLevel = function() {
var newElem = {
id: '1',
name: 'newName1',
nested: {
value: 'newNested1'
}
};
$scope.myCollection[0] = newElem;
};
$scope.changeSecondLevel = function() {
var newElem = {
id: '1',
name: 'name1',
nested: {
value: 'newNested1'
}
};
$scope.myCollection[0] = newElem;
};
}]);
Вы также можете запустить его в режиме этот JSFiddle.
Вопрос
Я понимаю, что AngularJS не видит сложные объекты в ng-options
по соображениям производительности. Но есть ли какое-либо обходное решение для этого, то есть я могу вручную вызвать повторный рендеринг? В некоторых сообщениях упоминается $timeout
или $scope.apply
как решение, но я не могу использовать их.