1

考虑以下 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 抛出一个异常。我需要在选择选项中更改反映运行时更改的名称属性。我试过了:

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

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

4

2 回答 2

1

淘汰赛不能直接做你想做的事。如果您的 ID 和 Name 字段包含相同的值,它可能会。但这不是你要求的,我通常不会自己做。

您可以通过引入 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 属性以进行显示。写属性是关键。它在选项数组中搜索名称匹配,然后将该数组元素设置为当前选项。

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

于 2012-12-16T17:17:45.703 回答
1

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

您可以手动将 JSON 转换为具有可观察属性的对象,也可以使用 为解决这个确切问题而编写的Knockout Mapping 插件:

用法很简单:

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 。

于 2012-12-16T18:53:37.470 回答