场景:我向服务器请求了一个部分。它给了我这个回报(它是假的,但代表了我所看到的):
{
PartNumber : "XYZ",
Description: "ABCFOO",
ProductClass: "Widget",
FieldList:[
{Name: "PROGRAM TYPE", Value: "Program3"},
{Name: "SHIP", Value: false},
{Name: "NOTES", Value: "SomeValue1"}
],
MoreStuff : [{
...
}]
}
注意FieldList的元素列表,这里是焦点。
服务器还给了我一些字段,类型和默认值的列表。它看起来像这样:
[
{FieldName : "PROGRAM TYPE", FieldType: "List", Defaults: [{Name:"Program 1", Value: "Program1"},{Name:"Program 2", Value: "Program2"},{Name:"Program 3", Value: "Program3"}]},
{FieldName : "SHIP", FieldType : "Boolean", Defaults: []},
{FieldName : "NOTES", FieldType: "TextArea", Defaults: []}
]
这是一个单独的REST调用,以及加载我的Part之前。我用它来创建Part的HTML页面的一部分。当我要求参与Part时,您可以看到它们与FieldList
部分的关系类似。
从那个"字段列表"和默认值 - 我在页面上生成适当的HTML元素。如果它是一个布尔字段类型,我创建一个复选框 - 如果它是一个列表,我创建一个SELECT(默认值中给出的选项),TextArea是一个文本区域等等。一切正常。它最终看起来像:
<input data-bind="textInput: PartNumber"/>
<textarea data-bind="textInput: Description"></textarea>
<!-- generating fieldlist - i create a pseudo attr because the field name can have spaces-->
<select field_label="PROGRAM TYPE"> <!-- how the heck do i bind to this??-->
<option value="Program1">Program 1</option>
<option value="Program2">Program 2</option>
<option value="Program3">Program 3</option>
</select >
<input type="checkbox" field_label="SHIP" value="true"/> <!-- or this, how to bind to it?!-->
<!-- end of field list generation -->
现在我把对象(我给出的部分)放到我的ViewModel中 - 这一切都只是游泳。我让它变得简单,只需使用ko.mapping.fromJS(rest_data);
就可以了。
数据绑定很困难 - 因为我能够绑定它。我的问题来自 - 我如何将FieldList
映射到我为服务器提供给我的字段生成的HTML?。我的数据/我的viewmodel对象中有FieldList
,带有我要映射到生成的东西的buncha。唯一真正的关键&#34;我有自己创建的field_label
,因为服务器的FieldName
可以有空格。
所以我想我要问的是,我有FieldList
那个数组。我在视图模型中有整个Part对象,它很好。如何取出FieldList
并将其映射到另一个对象的自生成字段集中(即,获取FieldList名称并将其绑定到具有field_label
的元素的元素相同的值?)
拼写出来 - 它如下:如何将FieldList
映射到名称为&#34;程序类型&#34;到具有&#34; PROGRAM TYPE&#34;。
我开始认为这样的事情可能是我应该走的方向: http://jsfiddle.net/MhdZp/128/ 但它超越了我的头脑。
答案 0 :(得分:1)
解决此问题的一种方法:
function Option(definition) {
this.definition = definition;
this.value = ko.observable();
this.templateName = 'input-template-' + definition.FieldType;
}
function ViewModel() {
var self = this;
// from REST call
var fieldDefinition = [{
FieldName: "PROGRAM TYPE",
FieldType: "List",
Defaults: [
{ Name: "Program 1", Value: "Program1" },
{ Name: "Program 2", Value: "Program2" },
{ Name: "Program 3", Value: "Program3" }
]
}];
self.options = ko.observableArray();
// for the sake of the example
self.options.push(new Option(fieldDefinition[0]));
// methods
self.optionByName = function (name) {
return ko.utils.arrayFirst(self.options(), function (option) {
return option.Name = name;
});
};
// poor man's init, imagine 2nd rest call instead
self.optionByName("PROGRAM TYPE").value("Program3");
}
和
<script type="text/html" id="input-template-List">
<label data-bind="text: definition.FieldName"></label>
<select data-bind="
value: value,
options: definition.Defaults,
optionsText: 'Name',
optionsValue: 'Value',
optionsCaption: 'Please select...'
"></select>
</script>
和
<div data-bind="foreach: options">
<div data-bind="template: templateName"></div>
</div>
根据需要添加更多模板,这应该很容易扩展。
jsFiddle:http://jsfiddle.net/0nxt2zte/