Knockout选项文本绑定

时间:2012-12-16 15:59:00

标签: jquery data-binding knockout.js

考虑以下HTML:

<select data-bind="options: assemblies, optionsText: 'Name', value: selectedAssembly">
</select>

Name <input type="text" data-bind="value: selectedAssembly().Name" />

我正在通过jQuery AJAX检索程序集数组:

[{"Id":1,"Name":"Foo"},
{"Id":2,"Name":"Bar"}]

selectedAssembly是一个observable,而()。Name会抛出异常。 我需要在select选项中更改运行时名称属性反映更改。 我试过了:

<p data-bind="with: selectedAssembly">
    Name <input type="text" data-bind="value: $data.Name" />
 </p>

这样我成功检索了Name属性,但只有当用户从框中选择另一个选项而不是实时时,才会更新其值更改。

2 个答案:

答案 0 :(得分:1)

淘汰赛无法直接做你想做的事。如果您具有包含相同值的ID和名称字段,则可以。但这不是你要求的,我通常不会自己做。

你可以通过引入ko.computed来实现。以下是我在http://jsfiddle.net/photo_tom/P8R8b/7/处工作的小提琴。

vm.selectedName = ko.computed({
    read: function() {
        var localVar = this.selectedAssembly(); // need for v8 compiler.
        if (localVar) {
            return localVar.Name();
        }
    },
    write: function(value) {
        var testValue = value.toLowerCase();
        var selArray = vm.assemblies();
        var l = selArray.length;
        for (var i = 0; i < l; i++) {
            var s = selArray[i].Name();
            if (s.toLowerCase() === testValue) {
                vm.selectedAssembly(selArray[i]);
            }
        }

    },
    owner: vm
});.  

这种方式的工作方式是read属性返回Name属性进行显示。 write属性是关键。它在options数组中搜索名称匹配,然后将该数组元素设置为当前选项。

但是,在我的应用程序中,我会使用一个自动完成的组合框,允许用户直接在select语句中输入所需的值。看看https://stackoverflow.com/a/7538860/136717。这就是我目前正在做的应用程序。

答案 1 :(得分:1)

您需要在Name数组中的项目上观察assemblies属性,以便能够编辑选择中的项目。

您可以手动使用可观察属性转换对象进行JSON,或者您可以使用编写的Knockout Mapping plugin来解决这个问题:

用法非常简单:

function viewModel() {
    var self = this;    
    self.selectedAssembly = ko.observable();

    // you need to have a default item in assemblies
    // otherwise ko will set undefinied to selectedAssembly because it the 
    // assemblies collection is empty at the begining
    // which brakes the selectedAssembly().Name binding
    self.assemblies = ko.observableArray([{Name: ""}]);    

    $.getJSON('http://localhost:9000/api/assemblies', function(data){
        ko.mapping.fromJSON(data, {}, self.assemblies)
    });
}

带有硬编码数据的简化JSFiddle