AngularJS中动态生成数据源的select如何设置选中选项?
AngularJS ng-options 赋值不生效解决方案
核心原因
问题基本由以下几个常见场景导致:
- 直接在
ng-options中调用返回新数组的方法:AngularJS 每轮脏检查都会执行someFunctionThatGeneratesData(),每次返回的数组都是全新实例,哪怕内容完全一致,AngularJS也会判定选项列表已更新,进而重置ngModel的绑定值。 - 赋值时机早于选项数据加载完成:如果
someFunctionThatGeneratesData()是异步方法,数据还没返回就提前给someObj.SomeEligibleStatusId赋值,此时还没有对应的选项可以匹配,自然不会生效。 - 赋值操作不在AngularJS上下文内:如果是在原生JS事件、
setTimeout、第三方库回调等非AngularJS管控的场景下修改绑定值,没有触发脏检查,视图不会同步更新。 - 绑定的目标对象未初始化:如果作用域上没有提前声明
someObj对象,直接给someObj.SomeEligibleStatusId赋值会把变量挂在全局window上,和视图的绑定无法关联。
修复方案
- 优先把选项数据缓存到作用域变量中
不要在ng-options里直接调用生成数组的方法,先把返回结果存到作用域的固定变量里:
// 数据生成后赋值给固定变量,避免每次脏检查都重新生成 $scope.statusOptions = someFunctionThatGeneratesData(param1, param2, param3);
修改HTML部分的ng-options绑定:
<select ng-model="someObj.SomeEligibleStatusId" ng-options="st.someId as st.someDescription for st in statusOptions"></select>
- 确保赋值在数据加载完成后执行
如果数据是异步获取的,在异步回调里再执行赋值操作:
// 异步方法示例 someFunctionThatGeneratesData(param1, param2, param3).then(function(res) { $scope.statusOptions = res; // 数据加载完成后再赋值 $scope.someObj.SomeEligibleStatusId = 1; })
- 非Angular上下文赋值手动触发脏检查
如果你的赋值操作是在Angular管控外的场景执行,手动调用$apply触发更新:
$scope.$apply(function() { someObj.SomeEligibleStatusId = 1; })
- 必须使用函数生成数组时补充正确的track by语法
如果确实需要动态生成数组,把track by放在ng-options的最后位置,通过id标识复用选项:
<select ng-model="someObj.SomeEligibleStatusId" ng-options="st.someId as st.someDescription for st in someFunctionThatGeneratesData() track by st.someId"></select>
- 提前初始化绑定对象
在控制器初始化阶段先声明绑定的父对象,避免变量挂载到全局:
// 控制器初始化时先声明 $scope.someObj = {};
内容的提问来源于stack exchange,提问作者Rod Ramírez
相关产品推荐
相关产品推荐

