AngularJS - 数据模型未在下拉列表中绑定
AngularJS - Data Model Doesn't Bind in Dropdown
HTML:
<select class="form-control" name="paramType" ng-change="setParamC($index)" ng-model="row.ParameterT" ng-options="item.ReferenceValue for item in pagemodel.ParamTList" required></select>
<select class="form-control" name="paramCat" ng-change="validatePCat($index)" ng-model="row.ParameterC" ng-options="item.ReferenceValue for item in pagemodel.ParamCList|filter:{ReferenceParentCode:row.ParameterT.ReferenceCode , ReferenceParentDomain:row.ParameterT.ReferenceDomain}" required></select>
<select class="form-control" name="paramName" ng-change="setParamV($index,0)" ng-model="row.ParameterN" ng-options="item.ReferenceValue for item in pagemodel.ParamNList|filter:{ReferenceParentCode:row.ParameterC.ReferenceCode , ReferenceParentDomain:row.ParameterC.ReferenceDomain}" required></select>
我有一个数据对象列表,这些对象通过 ajax 调用从服务器返回到前端。每个对象包含三个指向其他对象的属性(ParameterT
、ParameterC
和 ParameterN
)。
我还有三个对象列表,用作我的三个下拉列表的选项。这三个列表由服务器生成并通过相同的 ajax 调用发送到前端。
我的下拉选项的 3 个对象列表和我的主数据对象中的三个属性都是相同的对象类型。
这是我的第一个列表中的数据,ParamTList
,如前端所示:
(2) [{…}, {…}]
0:
$$hashKey:"object:503"
ReferenceCode:1
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Static"
__proto__:Object
1:
$$hashKey:"object:504"
ReferenceCode:2
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Dynamic"
__proto__:Object
length:2
__proto__:Array(0)
这是 ParameterT
对象:
{ReferenceDomain: "AGG_TIER_PARAMETER_TYPE", ReferenceCode: 2, ReferenceValue: "Dynamic", ReferenceParentDomain: null, ReferenceParentCode: null}
ReferenceCode:2
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Dynamic"
__proto__:Object
用作 ng-model
的 ParameterT
对象与 ng-options
列表中使用的一个对象相同,除了 $$hashKey
属性 .我猜这就是绑定没有发生的原因。 ParameterT
对象是一个子对象,但它的父对象,即主要数据对象,确实有一个 $$hashKey
属性.
对吗?
如果是,我该如何解决这个问题?
如果不是,我做错了什么?
我可以使用字符串而不是对象来完成所有这些操作,但是我将失去根据前一个下拉菜单的设置过滤下拉菜单选项的能力。
这目前在生产中有效,因为三个子属性是在前端设置的,通过循环遍历所有数据对象,然后循环遍历三个选项列表来搜索匹配项。这表现不佳,这就是为什么我试图将低效的东西转移到服务器。
解释:
您需要在每个 ng-options
中使用 track by
表达式,这是标准做法。
原因是,如果您不这样做,Angular 会在您的重复数据上创建一个 $$hashkey
属性 以进行 DOM 更改跟踪。而这个 $$hashkey
导致 select 对象与你的 http 数据不匹配,它没有 属性.
使用track by
,Angular只是比较指定的属性而不是整个对象的相等性(并且$$hashkey
无论如何都不会添加。)
解法:
因此,以您的 ParamT
为例,假设每个对象都有一个唯一的 属性(例如 ReferenceCode
),它看起来像:
ng-options="item.ReferenceValue for item in pagemodel.ParamTList track by item.ReferenceCode"
否则你可以试试:
ng-options="item.ReferenceValue for item in pagemodel.ParamTList track by $index"
按集合中的位置进行跟踪。
这是一个Working Fiddle;
HTML:
<select class="form-control" name="paramType" ng-change="setParamC($index)" ng-model="row.ParameterT" ng-options="item.ReferenceValue for item in pagemodel.ParamTList" required></select>
<select class="form-control" name="paramCat" ng-change="validatePCat($index)" ng-model="row.ParameterC" ng-options="item.ReferenceValue for item in pagemodel.ParamCList|filter:{ReferenceParentCode:row.ParameterT.ReferenceCode , ReferenceParentDomain:row.ParameterT.ReferenceDomain}" required></select>
<select class="form-control" name="paramName" ng-change="setParamV($index,0)" ng-model="row.ParameterN" ng-options="item.ReferenceValue for item in pagemodel.ParamNList|filter:{ReferenceParentCode:row.ParameterC.ReferenceCode , ReferenceParentDomain:row.ParameterC.ReferenceDomain}" required></select>
我有一个数据对象列表,这些对象通过 ajax 调用从服务器返回到前端。每个对象包含三个指向其他对象的属性(ParameterT
、ParameterC
和 ParameterN
)。
我还有三个对象列表,用作我的三个下拉列表的选项。这三个列表由服务器生成并通过相同的 ajax 调用发送到前端。
我的下拉选项的 3 个对象列表和我的主数据对象中的三个属性都是相同的对象类型。
这是我的第一个列表中的数据,ParamTList
,如前端所示:
(2) [{…}, {…}]
0:
$$hashKey:"object:503"
ReferenceCode:1
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Static"
__proto__:Object
1:
$$hashKey:"object:504"
ReferenceCode:2
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Dynamic"
__proto__:Object
length:2
__proto__:Array(0)
这是 ParameterT
对象:
{ReferenceDomain: "AGG_TIER_PARAMETER_TYPE", ReferenceCode: 2, ReferenceValue: "Dynamic", ReferenceParentDomain: null, ReferenceParentCode: null}
ReferenceCode:2
ReferenceDomain:"AGG_TIER_PARAMETER_TYPE"
ReferenceParentCode:null
ReferenceParentDomain:null
ReferenceValue:"Dynamic"
__proto__:Object
用作 ng-model
的 ParameterT
对象与 ng-options
列表中使用的一个对象相同,除了 $$hashKey
属性 .我猜这就是绑定没有发生的原因。 ParameterT
对象是一个子对象,但它的父对象,即主要数据对象,确实有一个 $$hashKey
属性.
对吗? 如果是,我该如何解决这个问题? 如果不是,我做错了什么?
我可以使用字符串而不是对象来完成所有这些操作,但是我将失去根据前一个下拉菜单的设置过滤下拉菜单选项的能力。
这目前在生产中有效,因为三个子属性是在前端设置的,通过循环遍历所有数据对象,然后循环遍历三个选项列表来搜索匹配项。这表现不佳,这就是为什么我试图将低效的东西转移到服务器。
解释:
您需要在每个 ng-options
中使用 track by
表达式,这是标准做法。
原因是,如果您不这样做,Angular 会在您的重复数据上创建一个 $$hashkey
属性 以进行 DOM 更改跟踪。而这个 $$hashkey
导致 select 对象与你的 http 数据不匹配,它没有 属性.
使用track by
,Angular只是比较指定的属性而不是整个对象的相等性(并且$$hashkey
无论如何都不会添加。)
解法:
因此,以您的 ParamT
为例,假设每个对象都有一个唯一的 属性(例如 ReferenceCode
),它看起来像:
ng-options="item.ReferenceValue for item in pagemodel.ParamTList track by item.ReferenceCode"
否则你可以试试:
ng-options="item.ReferenceValue for item in pagemodel.ParamTList track by $index"
按集合中的位置进行跟踪。
这是一个Working Fiddle;