剔除:不寻常的映射模式
Knockout : Unusual Mapping Pattern
场景:我向服务器请求一个零件。它还给了我这个(它是伪的,但代表了我所看到的):
{
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之前。我使用它来为部件创建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);
就可以了。
数据绑定是ducky的——因为我能够将它绑定到什么。我的问题来自于——我该如何将我的FieldList
映射到我为服务器提供的字段生成的HTML。我的数据/视图模型对象中有FieldList
,其中有一个buncha内容,我想映射到生成的内容。我拥有的唯一真正的"密钥"是我自己创建的field_label
,因为服务器的FieldName
可以有空间。
所以我想我要问的是,我有一个FieldList
的数组。我的视图模型中有整个Part对象,一切都很好。如何获取FieldList
并将其映射到另一个对象(即,获取FieldList名称并将其绑定到具有相同值的field_label
的元素?)
拼写如下:如何将名称为"PROGRAM TYPE"的FieldList
映射到field_label为"PROGRAM TYPE"的HTML元素。
我开始认为这样的事情可能是我应该走的方向:http://jsfiddle.net/MhdZp/128/但它超出了我的想象。
解决这一问题的一种方法:
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/
- 如何在映射数组中添加换行符
- ng映射方向备选方案
- Javascript,访问一个主要对象模块模式中的每个对象
- 无法通过数组映射绑定
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 试图在引导模式内动态生成图表,得到offsetWidth错误
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 同位素库错误:未捕获错误无布局模式包装生产线8
- 在DOM中查找一个模式并替换它's的内容使用jquery
- 如何缩短MongoDB ObjectId并在Mongoose模式中使用它
- 使用Scala Play Framework视图中的键检索映射值
- D3.js模式不适用于弧形或圆环图
- Webdriver.io pageObject模式-通过传递参数来定义元素选择器
- 模块模式和这个
- 带有let的JS/EECMAScript6私有字段的模式
- 我是否可以检测到javascript正在被卸载(作为调试模式)
- 执行动态模式弹出
- 剔除:不寻常的映射模式
- 图像映射链接没有加载模式
- 使用高效的主键模式在SQL数据库中存储2D映射