ko.toJSON似乎正在忽略字段 [英] ko.toJSON seems to be ignoring fields

查看:72
本文介绍了ko.toJSON似乎正在忽略字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用敲除js编码动态查询编辑器,但是ko.toJSON不会输出字段,除非已使用数据绑定表单元素对其进行了修改.请通过以下视图查看此jsfiddle :

I am coding a dynamic query editor with knockoutjs, but ko.toJSON is not outputting the fields until they have been modified by a data-bound form element. See this jsfiddle with the following view:

<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);

尽管视图模型显然具有预先初始化的字段(例如join属性),但直到用户在用户界面中对其进行更改时,它们才会显示在JSON对象中.

Though the view model clearly has fields pre-initialized (such as the join property), they're not showing up in the JSON object until the user changes them in the UI.

有人可以解释我在做什么错以及如何解决吗?实际上,这似乎是敲除js本身的错误.如果涉及到这一点,我将在构建查询时使用默认值(如果值不存在的话),但这似乎是一个糟糕的解决方案

Can someone please explain what I'm doing wrong and how to fix it? This actually seems like a bug with knockoutjs itself. If it comes down to it, I'll just use defaults when building the query if the values aren't there, but this seems like a crappy solution

推荐答案

您的代码中存在一个细微的问题,该问题已导致许多人不屑一顾.当对选择元素使用options绑定和value绑定时,需要在value之前指定options.

There is a subtle issue in your code that has caused many people to tear their hair out. When you use the options binding with the value binding on a select element, you need to specify options before value.

options绑定将构建可用选项,然后值绑定将强制使所选选项和视图模型值同步.如果您以错误的顺序排列它们,则value绑定将首先运行,并且会发现没有匹配的选项可供选择,因此它将值设置为null.

The options binding builds the available options and then the value binding enforces that the selected option and view model value are in sync. If you have them in the wrong order, then the value binding runs first and sees that there is not a matching option to select, so it sets the value to null.

以下是切换顺序的小提琴: http://jsfiddle.net/rniemeyer/32fYk/

Here is your fiddle with the order switched: http://jsfiddle.net/rniemeyer/32fYk/

这已经在github上登录了两次,最近一次是在这里: https://github.com/SteveSanderson/剔除/问题/58 .当前没有一种简单的方法来强制绑定在同一数据绑定中的另一个绑定之前运行.希望在某个时候可以解决这个问题.我可以想到一种可以通过检查两个绑定是否列出另一个绑定来专门处理这种情况的修复程序.

This has been logged on github a couple of times, most recently here: https://github.com/SteveSanderson/knockout/issues/58. There is currently not a simple way to enforce that a binding runs before another one in the same data-bind. Hopefully, at some point this will be addressed. I can think of a fix that would specifically handle this case by having the two bindings check if the other one is listed.

这篇关于ko.toJSON似乎正在忽略字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆