循环访问 Knockout - 绑定错误中的不同对象的数组
Looping over an array of different objects in Knockout - Binding Error
我正在尝试呈现页面的不同部分,并为单个数组中包含的不同项目应用适当的绑定。数组中的每个项目都可以具有不同的结构/属性。
例如,我们可以有 3 种不同的问题类型,与该问题关联的数据可以采用不同的格式。
数据
var QuestionTypes = { Textbox: 0, Checkbox: 1, Something: 2 }
var QuestionData = [
{
Title: "Textbox",
Type: QuestionTypes.Textbox,
Value: "A"
},
{
Title: "Checkbox",
Type: QuestionTypes.Checkbox,
Checked: "true"
},
{
Title: "Custom",
Type: QuestionTypes.Something,
Something: { SubTitle : "Something...", Description : "...." }
}
];
JavaScript
$(document).ready(function(){
ko.applyBindings(new Model(QuestionData), $("#container")[0]);
})
function QuestionModel(data){
var self = this;
self.title = ko.observable(data.Title);
self.type = ko.observable(data.Type);
self.isTextbox = ko.computed(function(){
return self.type() === QuestionTypes.Textbox;
});
self.isCheckbox = ko.computed(function(){
return self.type() === QuestionTypes.Checkbox;
});
self.isSomething = ko.computed(function(){
return self.type() === QuestionTypes.Something;
});
}
function Model(data){
var self = this;
self.questionData = ko.observableArray(ko.utils.arrayMap(data, function(question){
return new QuestionModel(question);
}));
}
.HTML
<div id="container">
<div data-bind="foreach: questionData">
<h1 data-bind="text: title"></h1>
<!-- ko:if isTextbox() -->
<div data-bind="text: Value"></div>
<!-- /ko -->
<!-- ko:if isCheckbox() -->
<div data-bind="text: Checked"></div>
<!-- /ko -->
<!-- ko:if isSomething() -->
<div data-bind="text: Something">
<h1 data-text: SubTitle></h1>
<div data-text: Description></div>
</div>
<!-- /ko -->
</div>
</div>
如果条件为真/假,则应用 if 条件中的绑定。这会导致 JavaScript 错误...因为并非集合中的所有对象都具有"Value"属性等。
Uncaught ReferenceError: Unable to process binding "foreach: function (){return questionData }"
Message: Unable to process binding "text: function (){return Value }"
Message: Value is not defined
有没有办法防止绑定应用于错误的对象?
概念 JSFiddle: https://jsfiddle.net/n2fucrwh/
请在不更改代码的情况下查看更新的小提琴手。仅在循环侧添加$data
https://jsfiddle.net/n2fucrwh/3/
<!-- ko:if isTextbox() -->
<div data-bind="text: $data.Value"></div>
<!-- /ko -->
<!-- ko:if isCheckbox() -->
<div data-bind="text: $data.Checked"></div>
<!-- /ko -->
<!-- ko:if isSomething() -->
<div data-bind="text: $data.Something"></div>
<!-- /ko -->
在循环中,您需要提供 $data.Value.It 似乎 值是与绑定冲突的淘汰赛的关键词。
首先,您的"问题模型"没有相应的属性:您仅从传入数据中创建"类型"和"标题"字段。
建议的解决方案:
您可以对不同的数据类型使用不同的模板。我已经更新了你的小提琴:
var QuestionTypes = { Textbox: 0, Checkbox: 1, Something: 2 }
var QuestionData = [
{
Title: "Textbox",
Type: QuestionTypes.Textbox,
templateName: "template1",
Value: "A"
},
{
Title: "Checkbox",
Type: QuestionTypes.Checkbox,
templateName: "template2",
Checked: "true"
},
{
Title: "Custom",
Type: QuestionTypes.Something,
templateName: "template3",
Something: "Something"
}
];
$(document).ready(function(){
ko.applyBindings(new Model(QuestionData), $("#container")[0]);
})
function QuestionModel(data){
var self = this;
self.title = ko.observable(data.Title);
self.type = ko.observable(data.Type);
self.data = data;
}
function Model(data){
var self = this;
self.questionData = ko.observableArray(ko.utils.arrayMap(data, function(question){
return new QuestionModel(question);
}));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/html" id="template1">
<div data-bind="text: Value"></div>
</script>
<script type="text/html" id="template2">
<div data-bind="text: Checked"></div>
</script>
<script type="text/html" id="template3">
<div data-bind="text: Something"></div>
</script>
<div id="container">
<div data-bind="foreach: questionData">
<h1 data-bind="text: title"></h1>
<!-- ko with: data -->
<!-- ko template: templateName -->
<!-- /ko -->
<!-- /ko -->
</div>
</div>
在上面的版本中,您可以摆脱"问题类型"。
更新 1
当然,您可以从问题类型中计算模板名称。
更新 2
错误原因的说明。如果检查原始视图模型:
function QuestionModel(data){
var self = this;
self.title = ko.observable(data.Title);
self.type = ko.observable(data.Type);
self.isTextbox = ko.computed(function(){
return self.type() === QuestionTypes.Textbox;
});
self.isCheckbox = ko.computed(function(){
return self.type() === QuestionTypes.Checkbox;
});
self.isSomething = ko.computed(function(){
return self.type() === QuestionTypes.Something;
});
}
您可以看到,"QuestionModel"具有以下属性:"title","type","isTextbox","isCheckbox"和"isSomething"。
因此,如果您尝试将模板绑定到"值","已检查"或"某些内容",则会收到错误,因为视图模型不包含此类属性。
将绑定语法更改为
<div data-bind="text: $data.Value"></div>
或类似的东西可以消除错误,但在这种情况下始终不会显示任何内容。
- Javascript(Angular)从一个对象数组到第二个数组查找值
- 在Javascript中转换对象数组
- 在JavaScript中通过索引从对象数组中获取值
- Backbone虹吸以获取对象数组
- 如何在DataTables 2.1中迭代对象数组
- Javascript-根据赋值顺序,按键合并对象数组
- 将事件附加到对象/数组
- jQuery$.inArray()总是返回-1和一个对象数组
- javascript处理一个对象数组以获得一个新的对象数组
- javascript在数组中获取对象数组中键的所有不同值
- 在对象数组中查找多个值的d3范围
- Undercore.js获取对象数组中键对象的值
- 在mongoose中使用正则表达式在对象数组中进行查询搜索
- 如何通过json对象数组为嵌套对象赋值
- 如何循环通过2个对象数组并通过匹配id进行合并
- 为对象数组创建列表项
- 如何使用javascript合并两个对象数组
- JSON到对象数组,并向每个对象添加项
- JavaScript:从对象数组中获取唯一值及其计数
- 按不同项目对对象数组进行排序