【发布时间】:2017-12-23 00:09:42
【问题描述】:
问题
我有一个组合框,基本上是一个select 元素,其中填充了ng-options 的复杂对象数组。当我在二级上更新集合的任何对象时,此更改不会应用于组合框。
这也是 AngularJS 网站上的documented:
请注意,
$watchCollection对对象的属性(或者如果模型是数组,则为集合中的项)进行浅层比较。这意味着更改比对象/集合内的第一层更深的属性不会触发重新渲染。
角度视图
<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>
角度控制器
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;
};
}]);
您也可以在 this JSFiddle 中实时运行它。
问题
我知道 AngularJS 出于性能原因不会监视 ng-options 中的复杂对象。 但是有什么解决方法可以解决这个问题,即我可以手动触发重新渲染吗?有些帖子提到$timeout 或$scope.apply 作为解决方案,但我都不能使用。
【问题讨论】:
-
你可以简单地把 $scope.selectedOption=newElem;在你的 $scope.changeSecondLevel() 函数中
-
不,我想更新收藏。直接设置所选元素不是一种选择。在我的应用程序中,
changeSecondLevel()执行一个 HTTP 请求,该请求返回一整套我重新分配给myCollection的新元素。为了简单起见,我在这里只选择了一个元素。 -
在您的应用程序中,
id的值在myCollection中是唯一的吗?当你说你重新分配myCollection时,你是做myCollection = ...还是像你的例子一样遍历列表并做myCollection[i] = ...?
标签: javascript angularjs refresh ng-options