我的模型有问题。我尝试从JSON加载模型,但它不能正常工作:( 我创建了级联选择列表。当我尝试将模型保存到JSON并在此之后从保存的JSON加载它时,它会导致选择列表的值错误。
这是我的约束力:
<div id="condition-template" type="text/html">
<div class="condition">
<select class="textbox1"
data-bind="options: entarea,
optionsText : 'displayName',
value: selectedArea " ></select>
<select class="textbox1"
data-bind="options: Selectedfields,
optionsText : 'fieldDisplayName',
value: selectedField "></select>
<select class="textbox1"
data-bind="options: Selectedcomparisons,
optionsText : 'comparsionDisplayName',
value: selectedComparison "></select>
<input class="textbox1" type="text" data-bind="value: value"></input>
<button data-bind='click: save'>Save to JSON</button>
<button data-bind='click: loadModel'>AddModel</button>
</p>
<textarea data-bind='value: lastSavedJson' rows='5' cols='60' > </textarea>
<inner type = "textarea" id="t_test"></inner>
</div>
</div>
我的模特是:
function Condition() {
var self = this;
var sqlArea = function(sqlAreaId, displayName) {
this.displayName = ko.observable(displayName);
this.sqlAreaId = ko.observable(sqlAreaId);
};
var field = function(fieldId, fieldDisplayName, sqlAreaId, fieldType) {
this.fieldId = ko.observable(fieldId);
this.fieldDisplayName = ko.observable(fieldDisplayName);
this.sqlAreaId = ko.observable(sqlAreaId);
this.fieldType = ko.observable(fieldType);
};
var comparison = function(comparsionId, comparsionDisplayName, fieldType) {
this.comparsionId = ko.observable(comparsionId);
this.comparsionDisplayName = ko.observable(comparsionDisplayName);
this.fieldType = ko.observable(fieldType);
};
self.templateName = "condition-template";
self.entarea = ko.observableArray([new sqlArea(1, "Client"),
new sqlArea(2, "Order")]);
self.selectedArea = ko.observable();
self.fields = ko.observableArray([new field( 1, "Name", 1, 1),
new field( 2, "Address", 1, 1),
new field( 3, "Phone number", 1, 1),
new field( 4, "Manager", 1, 1),
new field( 5, "Type", 1, 2),
new field( 6, "Order number", 2, 2),
new field( 7, "Sum", 2, 2),
new field( 8, "Date", 2, 3)]);
self.selectedField = ko.observable();
self.comparisons = ko.observableArray([new comparison( 1,">=", 2),
new comparison( 2,">", 2),
new comparison( 3,"<=", 3),
new comparison( 4,"IN from date", 3),
new comparison( 5,"IN from string", 1)
]);
self.selectedComparison = ko.observable();
//------------------------------------------------------------------------
//Cascading select list
self.Selectedfields = ko.dependentObservable(function () {
var area = self.selectedArea(), sqlAreaId;
if (area) {
sqlAreaId = area.sqlAreaId();
return ko.utils.arrayFilter(self.fields(), function(field) {
return field.sqlAreaId() === sqlAreaId;
});
}
return [];
}, self);
self.Selectedcomparisons = ko.dependentObservable(function() {
var field = self.selectedField(), fieldType;
if (field) {
fieldType = field.fieldType();
return ko.utils.arrayFilter(self.comparisons(),function(comparison) {
return comparison.fieldType() === fieldType;
});
}
return [];
}, self);
//-----------------------------------------------------------------------
self.value = ko.observable(0);
self.save = function() {
self.lastSavedJson(JSON.stringify( ko.mapping.toJS(self), null, 2));
var test = document.getElementById('t_test');
test.innerHTML = (JSON.stringify( ko.mapping.toJS(self), null, 2));
};
self.lastSavedJson = ko.observable("");
self.loadModel = function() {
var test = document.getElementById('t_test');
var data = JSON.parse(test.innerHTML);
ko.mapping.fromJS(data, {}, self);
/* var viewModel = {};
viewModel.model = ko.mapping.fromJS(data, {}, self);
self.updateFromModel(self, viewModel.model);*/
};
}
ko.applyBindings(new Condition());
UPDATE1: http://jsfiddle.net/3EWVR/2/
例如,当我选择order / sum /&gt; = / 8并将其保存为JSON然后我选择其他值(例如来自string / 0的client / address / in)并从JSON加载保存的数据模型,我期待获取原始输入(order / sum /&gt; = / 8)但是select item中没有任何值,它会在选择列表中显示值。
答案 0 :(得分:1)
我认为问题的根源是由于某些对象引用共享。考虑this fiddle中描述的不同情景。
但是,该基本说明需要进一步说明,因为Order
模型会导致第一<select>
内的重复,而Client
模型则不会。这两种类型也会导致第二个<select>
内的重复。
受影响的索引始终为[0],这解释了Client
不重复的原因。 受影响的0
部分的索引我尚未弄清楚。
由于我尚未调查的原因,请指定update callback
ko.mapping.fromJS( init, {
'selectedArea': {
update: function (options) {
return options.data;
}
}
}, new Condition())
ko.mapping options
参数中的似乎可以缓解这个问题。
<小时/> 另一种方法是引入
optionsValue
绑定并在需要时通过a ko.utils function 查找对象
仔细研究options
在实际源代码中的应用与我的缩小示例后,我仍然遇到了一些对象引用问题。所以我有applied my alternative approach。
<select>
元素现在使用optionsValue
绑定参数。影响来源的唯一地方是Selectedcomparisons
。您必须查找该字段才能访问fieldType
属性。
var selectedField = ko.utils.arrayFirst(self.Selectedfields(), function (field) {
return field.fieldId() === self.selectedField();
});
您正在解析JSON
然后ko.mapping.fromJS
,我改变了
ko.mapping.fromJSON(self.lastSavedJson(), options, self)
dependentObservables
无法按定义写入,因此我将其标记为已忽略
var options = {ignore: []}
var propertyNames = Object.keys(self);
for(index in propertyNames){
var property = propertyNames[index]
if(ko.isComputed(self[property])){
options.ignore.push(property)
}
};