ko.toJSON似乎忽略了字段

dae*_*s28 4 knockout.js

我正在使用knockoutjs编写动态查询编辑器,但是ko.toJSON在数据绑定表单元素修改之前不输出字段.通过以下视图查看此jsfiddle:

<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>
Run Code Online (Sandbox Code Playgroud)

这段代码:

// 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);
Run Code Online (Sandbox Code Playgroud)

虽然视图模型显然具有预初始化的字段(例如join属性),但在用户在UI中更改它们之前,它们不会显示在JSON对象中.

有人可以解释我做错了什么以及如何解决它?这实际上似乎是knockoutjs本身的一个错误.如果它归结为它,我只会在构建查询时使用默认值,如果值不存在,但这似乎是一个糟糕的解决方案

RP *_*yer 8

您的代码中存在一个微妙的问题,导致许多人将头发撕掉.当您使用options与绑定value一个选择元素绑定,你需要指定options之前value.

options结合建立可用的选项,然后将值绑定强制执行所选择的选项和视图模型值是同步的.如果你的顺序错误,那么value首先运行绑定并发现没有匹配的选项可供选择,因此它将值设置为null.

这是您改变订单的小提琴:http://jsfiddle.net/rniemeyer/32fYk/

这已经在github上记录了几次,最近一次在这里:https://github.com/SteveSanderson/knockout/issues/58.目前没有一种简单的方法可以强制绑定在同一个数据绑定中的另一个绑定之前运行.希望在某些时候这将得到解决.我可以通过让两个绑定检查是否列出另一个绑定来考虑一个专门处理这种情况的修复.

  • 当序列化为JSON时,将忽略值为null的属性,因此您可以通过在构造函数中将"criteria"强制为空字符串来更正输入元素(`this.criteria = ko.observable(''); `) (4认同)