【发布时间】:2016-09-07 12:55:50
【问题描述】:
我正在尝试映射数据,以便元素只有在值实际发生变化时才会重新呈现。
{
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 是一个对象数组而不是字符串数组。
如果我将地图中的“创建”更改为“更新”,一切似乎都已修复,但似乎每次都会重新渲染跨度,无论数据是否更改。
任何人都可以在我需要去的方向上帮助我,以便我可以
- 将类别数组从对象调整为字符串
- 仅重新渲染/渲染更改/新项目
这是一个 Fiddle 显示行为
【问题讨论】:
-
我想帮忙,所以我从creating a repro based off your code开始,但发现jsfiddle根本没有任何问题? (没有“[Object object]”的麻烦,没有重新渲染类别,什么都没有。)你能解释一下我的重现出了什么问题,或者将你的代码更新为 mcve 吗?
-
@Jeroen 感谢您为我准备了小提琴。我已经编辑了你开始的地方并复制了我看到的行为。我添加了一个计数器,它刚刚切换了 fakeData,但具有相同的确切数据。
标签: javascript knockout.js knockout-mapping-plugin