Knockout.js 映射忽略
Posted
技术标签:
【中文标题】Knockout.js 映射忽略【英文标题】:Knockout.js mapping ignore 【发布时间】:2013-12-26 14:41:04 【问题描述】:我们正在 .NET MVC 4 上使用 knockout.js 和 knockout.mapping.js。假设我有这样的 JSON:
"deliveryPointType": "0",
"deliveryPointTypes": [
"id": 0,
"text": "Pridėti rankiniu būdu"
,
"id": 1,
"text": "Siųsti visiems regiono objektams"
],
"showRegionSelection": false,
"showDeliveryPointSelection": true,
"regionId": "",
"userHasRegions": "False",
"propertyNames":
"deliveryPointTypeName": "Pridėti rankiniu būdu"
,
"initialMaterials": [
"quantity": 0,
"materialTypeId": "",
"propertyNames": ,
"validMaterial": true,
"showMaterialError": false,
"materialTypeAjax":
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Material/MaterialTypeNameLookup"
],
"deliveryBuildings": [
"clientId": "1",
"buildingId": "1",
"regionId": "",
"newBuilding": false,
"validClient": true,
"validBuilding": true,
"validRegion": true,
"showClientError": false,
"showBuildingError": false,
"showRegionError": false,
"propertyNames":
"clientName": "klientas",
"buildingName": "ASD project, Antagynės gatvė, Kaunas, Lietuvos Respublika"
,
"clientAjax":
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Task/PayerLookup"
,
"buildingAjax":
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/GetClientAddressListByQuery"
,
"regionAjax":
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
],
"hasNewBuildings": false,
"showBuildingValidation": false,
"showMinimumBuildingRequiredValidation": false,
"showMaterialValidation": false,
"validRegion": true,
"showRegionError": false,
"regionAjax":
"quietMillis": 300,
"cache": false,
"dataType": "json",
"type": "GET",
"url": "/lt-LT/Object/RegionNameLookup"
在表单提交失败时(如果出现问题/服务无效),它会重新填充以前的值。我们在使用$('#BuildingsJSON').val(ko.mapping.toJSON(viewModel.deliveryBuildings))
提交表单时将 ViewModel 转换为 JSON。
在重新填充表单时,我们解析 JSON,ko.mapping.fromJSON(deliveryBuildings, mapping, viewModel.deliveryBuildings)();
mapping
现在只是一个空对象(尝试“忽略”但没有运气)。
我们使用 select2 字段从列表中选择建筑物的地址(使用 ajax)。事情是,fromJSON 将几乎每个 json 属性填充为可观察的,我不需要。在 select2 打开时,我们得到一个异常:
未捕获的类型错误:对象函数 observable() if (arguments.length > 0) // 写
// Ignore writes if the value hasn't changed if (!observable['equalityComparer'] || !observable['equalityComparer'](_latestValue, arguments[0])) observable.valueWillMutate(); _latestValue = arguments[0]; if (DEBUG) observable._latestValue = _latestValue; observable.valueHasMutated(); return this; // Permits chained assignments else // Read ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read"
操作 返回_最新值; 没有方法“toUpperCase”
我已经在 ajax 调用的 type 属性上调试了它的中断位置。我认为我们需要将 ajax 属性排除在转换为 observable 之外。
那么,问题是:如何不将特定对象的特定属性转换为observable()
?使用映射插件是否足够,是否需要额外的插件或者甚至是不可能的?
【问题讨论】:
【参考方案1】:您是否考虑过在映射绑定中使用 copy
关键字?这只是将值复制到 js 属性中,而不是使其成为可观察的。
来自documentation:
var mapping =
'copy': ["propertyToCopy"]
ko.mapping.fromJS(data, mapping, viewModel);
【讨论】:
谢谢,我会试试的。而且 - 这是否可以“复制”整个对象? 好吧,它仍然将属性转换为可观察的。 你能告诉我你用过的代码吗,因为我用过 Copy 并且效果很好。 另外,如果你想复制整个对象,那你为什么要首先映射它呢? 感谢您建议使用 copy。它终于按预期工作了。至于为什么我们映射它 - 不知道。我自己是淘汰赛的新手,可能会有一些愚蠢的错误。以上是关于Knockout.js 映射忽略的主要内容,如果未能解决你的问题,请参考以下文章
在 knockout.js 中更改 observable 但不通知订阅者