将值绑定到复杂对象,提交简单属性

时间:2013-07-04 19:18:21

标签: knockout.js html-select

我有一个如下模型:

function Foo() {
    var self = this;    

    self.options = [{id: 1, text: "lorem"}, {id: 2, text: "ipsum"}];
    self.selectedValue = ko.observable(initialValue);

    self.selectedObject = ko.computed(function () {
        return ko.utils.arrayFilter(self.fields, function (f) {
            return f.id == self.selectedValue();
        })[0];
    });
}

当然,这是绑定到select

<select data-bind="options: options, 
                   optionsText: 'text',
                   optionsValue: 'id',
                   value: selectedValue">

ko.computed hack是因为我有另一个绑定(在另一个对象中,未显示)需要访问完整对象,而值需要是一个普通的Id,所以可以提交(I使用标准form,而不是自定义调用)

我想摆脱黑客攻击(我在更多的地方做了)。理想情况下,我会在我的模型中定义一个selected属性,该属性具有该对象,但提交时select值将是正确的。

它必须以两种方式工作:我可能有一个初始值来选择。

这可行吗?我应该研究自定义绑定吗?它已经存在吗?

我可以反过来做(就像我现在正在做的那样),但我希望它更干净。我想我可以写一个lookup(array, property, value)助手,但也许有更好的方法。

1 个答案:

答案 0 :(得分:0)

我认为你可以使用扩展器。例如,以下一个:

ko.extenders.plainObject = function(target, options) {
    target.plainValue = function() {
        return ko.utils.arrayFilter(options, function (f) {
            return f.id == target();
        })[0];        
    }
    return target;
};

你必须像往常一样调用selectedValue.plainValue()来获取对象,并选择selectValue()来获取id。请看一下这个jsfiddle:http://jsfiddle.net/C5f98/2/

您可以在任何地方重复使用扩展器。

编辑:您甚至可以通过将字段作为选项传递比较(而不是硬编码“id”)来使其更通用。例如:http://jsfiddle.net/pUudD/