我正在编写一个带有knockoutjs的动态查询编辑器,但是ko.toJSON不会输出字段,直到它们被数据绑定的表单元素修改为止。见this jsfiddle有以下几种观点:ko.toJSON似乎忽略字段
<span data-bind="template: {name: 'filterGroupTemplate', data: viewModel}"></span>
<script type="text/x-jquery-tmpl" id="filterGroupTemplate">
<div class="filterGroup">
<div class="filterGroupParams">
Match
<select name="join" data-bind="value: join, options: joins"></select>
of the following rules:
<button class="addFilter" data-bind="click: addFilter">+</button>
<button class="addGroup" data-bind="click: addGroup">{...}</button>
<button class="removeGroup">x</button>
</div>
<span data-bind='template: {name: "filterTemplate", foreach: filters }'></span>
</div>
</script>
<script type="text/x-jquery-tmpl" id="filterTemplate">
<div class="filter">
{{if $data.filters }}
<div data-bind='template: "filterGroupTemplate"'>
</div>
{{else}}
<select data-bind="value: field, options: fields"></select>
<select data-bind="value: modifier, options: modifiers"></select>
<input type="text" data-bind="value: criteria" />
<button>x</button>
{{/if}}
</div>
</script>
<h2>ViewModel JSON</h2>
<div data-bind="text: dev()"></div>
而这种代码:
// filter class
var Filter = function() {
this.field = ko.observable();
this.modifier = ko.observable();
this.criteria = ko.observable();
};
// filter group class
var FilterGroup = function() {
// Include a blank filter in every group
this.join = ko.observable('All');
this.filters = ko.observableArray([new Filter()]);
this.addFilter = function() {
var filter = new Filter();
this.filters().push(filter);
this.filters.valueHasMutated();
};
this.addGroup = function() {
var group = new FilterGroup();
this.filters().push(group);
this.filters.valueHasMutated();
};
};
// Data
var joins = ['All', 'Any'];
var modifiers = [
'equals',
'not equal to',
'less than',
'greater than',
'contains',
'does not contain',
'starts with'
];
var fields = ['f1','f2','f3'];
var viewModel = new FilterGroup();
function dev(){
return ko.toJSON(viewModel);
}
ko.applyBindings(viewModel);
尽管视图模型显然有场预先初始化(如联接属性),他们没有显示了直到用户在UI中更改它们为止的JSON对象。
有人可以请解释我做错了什么,以及如何解决它?这实际上就像是一个knockoutjs本身的bug。如果涉及到它,如果值不存在,我将在构建查询时使用默认值,但这似乎是一个蹩脚的解决方案
非常感谢!这工作很好。我唯一的问题是,这个问题似乎仍然适用于输入元素上的约束数据绑定,但这很重要,因为不应该有空白的输入值。现在添加删除项目的功能... 为了记录,您的博客是我的谷歌搜索的主要来源 - 我花了几个小时阅读几乎所有的东西。 – daedalus28
当序列化为JSON时,值为null的属性将被忽略,因此您可以通过将'criteria'强制为Filter的构造函数中的空字符串来更正您的输入元素('this.criteria = ko.observable('') ;') –
谢谢,那也工作得很好:) – daedalus28