我从REST端点获得以下响应,我需要使用值填充字典。 json看起来像这样:{" name":" A"," id:" A"," properties":{ "说明":" A","文字":" A","号码":"一个& #34;}}最终,我将获得这个json对象的数组。
我在我的ajax成功回调中尝试了以下内容:
console.log(result)
for (x in result){
console.log(result[x])
if (x === 'object'){
for (y in x){
console.log(x[y]);
}
}
}
这真的不是我想要的。如果用户选择名称,我需要能够将属性值加载到knockout变量中。
答案 0 :(得分:0)
我认为你的问题有两个方面:
这可以自动完成(例如,通过评论中链接的ko-mapping插件),也可以手动完成。我赞成手动映射。基础知识:
解析JSON。
例如:从'{ "name": "A" }'
到{ name: "A" }
通过prototype
,observable
或computed
属性添加功能。
例如:从{ name: "A" }
到{ name: ko.observable("A"), index: 0,
/* ... */ }
一旦创建了一组视图模型,您就需要一个地方来管理选择。基础知识:
this.items = ko.observableArray([ { name: "A" }, { name: "B" } ]);
this.selection = ko.observable(items[0]);
您可以将项目和选择数据绑定到UI。例如,使用<select>
元素:
<select data-bind="options: items, optionsText: 'name', value: selection></select>
这样就完成了链:json
&gt; array of objects
&gt; array of viewmodels
+ selected viewmodel reference
。
现在,唯一的挑战是确保您可以从服务器重新加载数据而不会丢失选择。为此,您可以向viewmodel添加update
方法来设置可观察属性,或者替换所有视图模型并存储选定的id
而不是对对象的引用。
一起作为例子:
var createItem = function (obj) {
// Up to you how you map to "viewmodels",
// If you want two-way binding (for editing),
// wrap in an observable.
// Example for 1-way binding
return Object.assign({
name: obj.name,
id: obj.id,
randomNr: Math.random()
}, Object.keys(obj.properties).reduce(function(res, key) {
res[key] = obj.properties[key];
return res;
}, {}));
};
var VM = function() {
this.rawData = ko.observableArray([]);
// Create "item" view models from the array of objects
this.items = ko.pureComputed(function() {
return this.rawData().map(createItem);
}, this);
// Store items by `id` prop. (Could also be a plain object)
var itemMap = ko.pureComputed(function() {
return new Map(
this.items().map(function(item) {
return [item.id, item];
})
);
}, this);
// Store the id of the selected item
this.selectedId = ko.observable(null);
// Whenever either the selected id, _or_ the array of items changes,
// update the selected item
this.selectedItem = ko.pureComputed(function() {
return itemMap().get(this.selectedId());
}, this);
};
VM.prototype.loadData = function(json) {
// Hardcoded
json = '[{"name":"A", "id":"A", "properties":{"description":"A", "text":"A", "number":"one"}}, {"name":"B", "id":"B", "properties":{"description":"B", "text":"B", "number":"two"}},{"name":"C", "id":"C", "properties":{"description":"C", "text":"C", "number":"three"}}]';
// Might want to wrap in a try catch
this.rawData(JSON.parse(json));
}
var vm = new VM();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: items,
optionsText: 'name',
optionsValue: 'id',
value: selectedId"></select>
<p>Your selection:<p>
<div data-bind="with: selectedItem">
<h3>Name: <span data-bind="text: name"></span></h3>
<h4>Description:<span data-bind="text: description + randomNr"></span></h4>
<p>Nr:<span data-bind="text: number"></span></p>
</div>
<button data-bind="click: loadData">load data</button>