当通过AJAX绑定选项时,是否可以将select元素的默认值传递给Knockout

Is it possible to pass to Knockout the default value of a select element when binding the options through AJAX?

本文关键字:默认 元素 select 默认值 值传 Knockout 绑定 AJAX 选项 是否      更新时间:2023-09-26

我需要通过两个不同的AJAX调用来获取<select />的当前值和可用选项(由于几个原因,我无法对它们进行排队/连锁)。

我不知道这是否重要,但读取当前值的调用在每次读取可用选项之前完成。

使用Knockout 2.0.0和Knockout Mapping 2.0.3,我将select与data-bind="options: values, value: valueComputed"绑定,但我发现Knockout正在删除/忽略第一个AJAX调用设置的值,直到获取可用选项的调用完成,才可能设置当前值。

这是正确的吗?是否可以告诉Knockout"这是当前值,当可用选项可用时选择它"?

经过几次测试,我想出了一个拼凑的方法:我没有将一个普通的可观测值与选择的值绑定,而是使用了一个计算的可观测量,在这里我截取了值,如果新值未定义,则不会改变基本的可观测。

我在做什么坏事吗?

jsFiddle示例:http://jsfiddle.net/KeNUU/

我正在使用的JavaScript代码:

var viewModel = function () {
    var self = this;
    // The underlying observable where
    // the selected value is stored.
    self.value = ko.observable();
    // The observable bound to
    // the value of the drop down.
    self.values = ko.mapping.fromJS([]);
    // Use a computed observable to intercept the undefined
    // value placed by KnockOut when binding the drop down.
    self.valueComputed = ko.computed({
        "read": function () {
            return ko.utils.unwrapObservable(self.value);
        },
        "write": function (value) {
            // Update the underlying observable only when
            // there is a value, if it's undefined ignore it.
            if (value) {
                self.value(value);
            }
        }
    });
    // Simulate the AJAX request which fetches the actual value,
    // this request must complete before the second one.
    setTimeout(function () {
        self.valueComputed("b");
    }, 1000 * 1);
    // Simulate the AJAX request which fetches the available values,
    // this reqest must complete after the first one.
    setTimeout(function () {
        ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
    }, 1000 * 2);
};
$(document).ready(function () {
    ko.applyBindings(new viewModel());
});

我不认为你所做的会给你带来问题,但你正在绕过KO的逻辑,以确保与值绑定的是你的选项中的有效选择。此外,如果您使用optionsCaption提供一个空白选项,那么您将无法清除您的值。在你的情况下,这可能无关紧要。

我认为一个更简单的选择是将初始值缓存在一个不可观察的值中,然后在列表返回时使用它来填充value。如果列表先出现,那么就没有初始值,它可以正常工作。

类似于:

setTimeout(function () {
    self.initialValue = "b";
    self.value("b");
}, 1000 * 1);
// Simulate the AJAX request which fetches the available values,
// this reqest must complete after the first one.
setTimeout(function () {
    ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
    if (self.initialValue) {
         self.value(self.initialValue);
         self.initialValue = null;
    }    
}, 1000 * 2);

http://jsfiddle.net/rniemeyer/gB3E5/

现在,您可以提前处理这一问题,而无需每次更改下拉列表时都要计算一个可观察的截距。