淘汰:如何设置选项为javascript对象的选择框的值?

淘汰:如何设置选项为javascript对象的选择框的值?,javascript,knockout.js,Javascript,Knockout.js,我有一个select元素,它使用选项绑定绑定到一个复杂javascript对象列表: 然而,就我所见,这涉及到修改值绑定。我还有其他选择吗?我能用其他方法解决这个问题吗?扩展器?自定义绑定处理程序?我已选择一个绑定来解决此问题,请检查我的绑定集合 演示,下拉列表在页面的末尾 代码 我已选择一个绑定来修复此问题,请检查我的绑定集合 演示,下拉列表在页面的末尾 代码 我通过将getCountryByPop方法附加到availableCountries数组,然后调用它来设置可观察对象的值,解决了类

我有一个select元素,它使用选项绑定绑定到一个复杂javascript对象列表:


然而,就我所见,这涉及到修改值绑定。我还有其他选择吗?我能用其他方法解决这个问题吗?扩展器?自定义绑定处理程序?

我已选择一个绑定来解决此问题,请检查我的绑定集合

演示,下拉列表在页面的末尾

代码


我已选择一个绑定来修复此问题,请检查我的绑定集合

演示,下拉列表在页面的末尾

代码


我通过将getCountryByPop方法附加到availableCountries数组,然后调用它来设置可观察对象的值,解决了类似的问题:

availableCountries.getCountryByPop = function(pop) {
    var ret;
    this().forEach(function(country) {
        if (country.countryPopulation == pop) {
            ret = country;
        }
    });
    return ret;
};

...

viewModel.selectedCountry(availableCountries.getCountryByPop(9));

我通过将getCountryByPop方法附加到availableCountries数组,然后调用它来设置可观察对象的值,解决了类似的问题:

availableCountries.getCountryByPop = function(pop) {
    var ret;
    this().forEach(function(country) {
        if (country.countryPopulation == pop) {
            ret = country;
        }
    });
    return ret;
};

...

viewModel.selectedCountry(availableCountries.getCountryByPop(9));

是的,这应该对我有用。聪明的我对它做了一些修改。一是允许选项发生变异。另一种方法是允许optionsKey成为函数,以防您想要进行更复杂的比较,比如optionsValue如何成为函数。我还将disposeWhenNodeIsRemoved添加到了计算结果中。很高兴你喜欢它,关于计算的,它应该被JS引擎垃圾收集如果绑定被移除,我将你的更改添加到GithubYes,这应该对我有用。聪明的我对它做了一些修改。一是允许选项发生变异。另一种方法是允许optionsKey成为函数,以防您想要进行更复杂的比较,比如optionsValue如何成为函数。我还将disposeWhenNodeIsRemoved添加到了计算结果中。很高兴您喜欢它,关于计算,如果移除绑定,JS引擎应该会对它进行垃圾收集。我将您的更改添加到Github
ko.bindingHandlers.selected = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var selected = valueAccessor();
        var items = ko.utils.unwrapObservable(allBindingsAccessor().options);
        var key = allBindingsAccessor().optionsKey ? allBindingsAccessor().optionsKey : allBindingsAccessor().optionsText;

        var observable = ko.computed({
            read: function () {
                var value = ko.utils.unwrapObservable(selected);
                return ko.utils.arrayFirst(items, function (item) {
                    return value != null ? ko.utils.unwrapObservable(item[key]) == ko.utils.unwrapObservable(value[key]) : false;
                });
            },
            write: function (value) {
                writeValueToProperty(selected, allBindingsAccessor, "selected", value);
            }
        });

        ko.applyBindingsToNode(element, { value: observable });
    }
};
availableCountries.getCountryByPop = function(pop) {
    var ret;
    this().forEach(function(country) {
        if (country.countryPopulation == pop) {
            ret = country;
        }
    });
    return ret;
};

...

viewModel.selectedCountry(availableCountries.getCountryByPop(9));