gpt4 book ai didi

javascript - knockout 映射创建/更新时出现问题

转载 作者:行者123 更新时间:2023-11-30 00:09:15 26 4
gpt4 key购买 nike

我正在尝试映射数据,以便元素仅在值实际更改时才重新呈现。

{
Apps : [
{
"Categories" : [{
"Name" : "#Some,#More,#Tags,#For,#Measure"
}
],
"Concentrator" : "",
"Health" : 1,
"Id" : 2648,
"Ip" : "1.1.1.1",
"IsDisabled" : true,
"IsObsolete" : false,
"Name" : "",
"Path" : "...",
"SvcUrl" : "http://1.1.1.1",
"TimeStamp" : "\/Date(1463015444163)\/",
"Type" : "...",
"Version" : "1.0.0.0"
}
...
]
...
}

var ViewModel = function() {
self.Apps = ko.observableArray([]);
}

var myModel = new ViewModel();

var map = {
'Apps': {
create: function (options) {
return new AppModel(options.data);
},

key: function(data) { return ko.utils.unwrapObservable(data.Id); }
}
}

var AppModel = function(data){
data.Categories = data.Categories[0].Name.split(',');
ko.mapping.fromJS(data, { }, this);
return this;
}

function UpdateViewModel() {
return api.getDashboard().done(function (data) {
ko.mapping.fromJS(data, map, myModel);
});
}

loopMe(UpdateViewModel, 5000);

function loopMe(func, time) {
//Immediate run, once finished we set a timeout and run loopMe again
func().always(function () {
setTimeout(function () { loopMe(func, time); }, time);
});
}

<script type="tmpl" id="App-template">
<div>
<!-- ko foreach: Categories -->
<span class="btn btn-default btn-xs" data-bind="text:$data"></span>
<!-- /ko -->
</div>
</script>

在第一次运行 UpdateViewModel 时,我将按预期看到 5 个跨度。在第二次调用时,接收到相同的数据,它被更新为一个显示 [Object object] 的跨度,这是因为它仍然认为 Categories 是一个对象数组而不是一个字符串数组。

如果我在我的 map 中将“创建”更改为“更新”,一切似乎都是固定的,但似乎每次都会重新渲染跨度,无论数据是否更改。

谁能帮我指明我需要去的方向

  1. 将类别数组从对象调整为字符串
  2. 仅重新渲染/渲染更改/新项目

这是一个Fiddle显示行为

最佳答案

问题在于这些行:

var AppModel = function(data){
data.Categories = data.Categories[0].Name.split(','); // <-- mainly this one
ko.mapping.fromJS(data, { }, this);
return this;
}

有两个问题:

  1. 您改变了 data 对象,它(至少在我们的重现中)改变了 data 引用的原始对象。因此,第一次传入一个 fakeData 对象时,该对象会在原地发生变异,并将永远“固定”。

  2. 您在 AppModel constructor 函数中改变它,该函数仅在第一次被调用。根据您的 key 函数,第二次构造函数应该被调用,但是 ko-mapping 应该保留原始对象并在适当的位置改变它。但它会使用“错误”格式化的 data.Categories 属性。

在我看来,正确的修复方法是在您的数据层中,我们已经在重现中对其进行了模拟,因此我的回答向您展示如何操作是没有意义的。

另一种更 hacky 的方法是在映射中使用 update 方法,如下所示:

update: function(options) {
if (!!options.data.Categories[0].Name) {
options.data.Categories = options.data.Categories[0].Name.split(',');
}
return options.data;
},

当它遇到一个“未修改”的数据对象时,它会做同样的改变。参见 this jsfiddle实际解决方案。

关于javascript - knockout 映射创建/更新时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37174224/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com