我从这里分叉代码: http://kindohm.github.io/knockout-query-builder/
代码在客户端很好用。 但是当我尝试将viewModel保存为JSON然后从服务器检索数据时,UI永远不会刷新。
这是原始的viewModel:
window.QueryBuilder = (function(exports, ko){
var Group = exports.Group;
function ViewModel() {
var self = this;
self.group = ko.observable(new Group());
// the text() function is just an example to show output
self.text = ko.computed(function(){
return self.group().text();
});
}
exports.ViewModel = ViewModel;
return exports;
})(window.QueryBuilder || {}, window.ko);
我将向viewModel添加下一个方法
self.Save = function () {
console.log(ko.toJSON(self));
}
在视图中添加了此按钮
<input type="submit" value="Save" data-bind="click: Save"/>
这是Group viewModel:
window.QueryBuilder = (function(exports, ko){
var Condition = exports.Condition;
function Group(data){
var self = this;
self.templateName = data.templateName;
self.children = ko.observableArray(data.children);
self.logicalOperators = ko.observableArray(data.logicalOperators);
self.selectedLogicalOperator = ko.observable(data.selectedLogicalOperator);
// give the group a single default condition
self.children.push(new Condition());
self.addCondition = function(){
self.children.push(new Condition());
};
self.addGroup = function(){
self.children.push(new Group());
};
self.removeChild = function(child){
self.children.remove(child);
};
// the text() function is just an example to show output
self.text = ko.computed(function(){
var result = '(';
var op = '';
for (var i = 0; i < self.children().length; i++){
var child = self.children()[i];
console.log(child);
result += op + child.text();
op = ' ' + self.selectedLogicalOperator() + ' ';
}
return result += ')';
});
}
exports.Group = Group;
return exports;
})(window.QueryBuilder || {}, window.ko);
所以当我按下“保存”按钮时,控制台会从这个viewModel显示JSON,这里一切都很好。
这是返回的JSON:
{"group":{"templateName":"group-template","children":[{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"},{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"},{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"}],"logicalOperators":["AND","OR"],"selectedLogicalOperator":"AND","text":"(Points = 0 AND Points = 0 AND Points = 0)"},"text":"(Points = 0 AND Points = 0 AND Points = 0)"}
我做了一个简单的黑客来避免与服务器的连接,所以我把json复制并粘贴到load事件上并发送到viewModel的构造函数:
var vm;
window.addEventListener('load', function(){
var json = {"group":{"templateName":"group-template","children":[{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"},{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"},{"templateName":"condition-template","fields":["Points","Goals","Assists","Shots","Shot%","PPG","SHG","Penalty Mins"],"selectedField":"Points","comparisons":["=","<>","<","<=",">",">="],"selectedComparison":"=","value":0,"text":"Points = 0"}],"logicalOperators":["AND","OR"],"selectedLogicalOperator":"AND","text":"(Points = 0 AND Points = 0 AND Points = 0)"},"text":"(Points = 0 AND Points = 0 AND Points = 0)"};
vm = new QueryBuilder.ViewModel(json);
ko.applyBindings(vm);
}, true);
然后我修改viewModel以重新接收json参数
window.QueryBuilder = (function(exports, ko){
var Group = exports.Group;
function ViewModel(json) {
var self = this;
self.group = ko.observable(json.group);
// the text() function is just an example to show output
self.text = ko.computed(function(){
return self.group().text();
});
self.Save = function () {
console.log(ko.toJSON(self));
}
}
exports.ViewModel = ViewModel;
return exports;
})(window.QueryBuilder || {}, window.ko);
当我刷新index.html时,视图永远不会正确加载并在JS控制台上显示此错误:
TypeError: self.group(...).text is not a function
return self.group().text();
有人知道我的错误在哪里?
我遇到的最后一个问题与孩子的text()函数有关。 我通过使用try / catch解决了这个问题。所以当viewModel是new时它有text()函数,但是当这是loadad时text()不存在,所以我直接从“text”字段中取值。
try {
result += op + child.text();
}
catch(err) {
result += op + child.text;
}
问题出在Group类和Condition类上。 这是当前和正在运行的代码:
window.QueryBuilder = (function(exports, ko){
var Condition = exports.Condition;
function Group(data){
var self = this;
self.templateName = data.templateName;
self.children = ko.observableArray(data.children);
self.logicalOperators = ko.observableArray(data.logicalOperators);
self.selectedLogicalOperator = ko.observable(data.selectedLogicalOperator);
// give the group a single default condition
self.children.push(new Condition(data.children[0]));
self.addCondition = function(){
self.children.push(new Condition());
};
self.addGroup = function(){
self.children.push(new Group());
};
self.removeChild = function(child){
self.children.remove(child);
};
// the text() function is just an example to show output
self.text = ko.computed(function(){
var result = '(';
var op = '';
for (var i = 0; i < self.children().length; i++){
var child = self.children()[i];
try {
result += op + child.text();
}
catch(err) {
result += op + child.text;
}
op = ' ' + self.selectedLogicalOperator() + ' ';
}
return result += ')';
});
}
exports.Group = Group;
return exports;
})(window.QueryBuilder || {}, window.ko);
window.QueryBuilder = (function(exports, ko){
function Condition(data){
var self = this;
self.templateName = data.templateName;
self.fields = ko.observableArray(data.fields);
self.selectedField = ko.observable(data.selectedField);
self.comparisons = ko.observableArray(data.comparisons);
self.selectedComparison = ko.observable(data.selectedComparison);
self.value = ko.observable(data.value);
// the text() function is just an example to show output
self.text = ko.computed(function(){
return self.selectedField() +
' ' +
self.selectedComparison() +
' ' +
self.value();
});
}
exports.Condition = Condition;
return exports;
})(window.QueryBuilder || {}, window.ko);
答案 0 :(得分:2)
而不是self.group = ko.observable(new Group());
,您应该采用与加载json.group
上类似的方法,但这次会传递Group
中的 self.group = ko.observable(new Group(json.group));
数据
Group
我没有看到定义{{1}}的位置,但是你应该确保它能够处理你现在传入的JSON并将其转换为observable。