Knockout.JS Observable Array 通过 AJAX 绑定到 DropDownList

发布于 2025-01-03 13:23:44 字数 2186 浏览 1 评论 0原文

我试图用数据库中的一些下拉选项填充我的视图模型。我想跟踪所选对象,因为它具有我在其他地方的自定义绑定中使用的属性。

我使用“空白”值初始化可观察量,以便在绑定发生并且我的自定义绑定起作用时正确设置它。服务器响应后,我将数据转换为可观察的数组,下拉列表将显示选项。

这是 JavaScript 代码:

ko.bindingHandlers.jq_fade = {
    init: function (element, valueAccessor) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
    },
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();
        ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
    }
};

function Firm(id, name, outsideCounsel) {
    this.name = name;
    this.id = id;
    this.outsideCounsel = outsideCounsel;
}

function RequestViewModel() {
    var self = this,
        ONE_DAY = 1000 * 60 * 60 * 24;


    self.firm = ko.observable(new Firm(-1, "", false));

    $.post(ajaxAddress + 'LoadFirms', function (data) {
        var mappedFirms = $.map(data.d, function (item) {
            return new Firm(item.OrganizationLookupID, item.OrganizationLookupName, item.IsExternalCounselFirm);
        });
        self.availableFirms(mappedFirms);
        self.firm(self.availableFirms()[0]);
    });
}


$(document).ready(function () {
    model = new RequestViewModel();
    ko.applyBindings(model);
});

这是相关的 HTML

<span data-bind="jq_fade: firm().outsideCounsel">
    Outside Counsel
    <input type="text" id="outsideCounsel" data-bind="value: outsideCounsel" />
</span>

我希望 DIV 仅在选定的公司是外部法律顾问时才显示。如果删除行 data-bind="jq_fade:firm().outsideCounsel,一切正常。如果我同步调用 $.post(),它就可以工作。我认为 jq_fade 中的 init 函数有问题

我收到的错误是:

未捕获错误:无法解析绑定。 消息:类型错误:无法调用未定义的方法“outsideCounsel”; 绑定值:jq_fade:firm().outsideCounsel()

我明白 Knockout 告诉我什么,我只是不确定 firm() 如何成为 undefined 因为我设置一个初始值。

I am trying to fill my view model with some drop down options from the database. I want to keep track of the selected object because it has properties on it that I am using in a custom binding elsewhere.

I initialize the observable with a "blank" value so that it's properly set when the binding occurs and my custom binding works. Once the server responds, I morph the data to an observable array and the drop down list displays the options.

Here is the JavaScript code:

ko.bindingHandlers.jq_fade = {
    init: function (element, valueAccessor) {
        // Initially set the element to be instantly visible/hidden depending on the value
        var value = valueAccessor();
        $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
    },
    update: function (element, valueAccessor) {
        // Whenever the value subsequently changes, slowly fade the element in or out
        var value = valueAccessor();
        ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
    }
};

function Firm(id, name, outsideCounsel) {
    this.name = name;
    this.id = id;
    this.outsideCounsel = outsideCounsel;
}

function RequestViewModel() {
    var self = this,
        ONE_DAY = 1000 * 60 * 60 * 24;


    self.firm = ko.observable(new Firm(-1, "", false));

    $.post(ajaxAddress + 'LoadFirms', function (data) {
        var mappedFirms = $.map(data.d, function (item) {
            return new Firm(item.OrganizationLookupID, item.OrganizationLookupName, item.IsExternalCounselFirm);
        });
        self.availableFirms(mappedFirms);
        self.firm(self.availableFirms()[0]);
    });
}


$(document).ready(function () {
    model = new RequestViewModel();
    ko.applyBindings(model);
});

Here is the relevant HTML

<span data-bind="jq_fade: firm().outsideCounsel">
    Outside Counsel
    <input type="text" id="outsideCounsel" data-bind="value: outsideCounsel" />
</span>

I want that DIV to show only if the selected firm is an outside counsel. If remove the line data-bind="jq_fade: firm().outsideCounsel, everything works fine. If I make the $.post() calls synchronously, it works. I'm thinking it's something wrong with my init function in jq_fade.

The error I receive is:

Uncaught Error: Unable to parse bindings.
Message: TypeError: Cannot call method 'outsideCounsel' of undefined;
Bindings value: jq_fade: firm().outsideCounsel()

I understand what Knockout is telling me, I'm just not sure how firm() can ever be undefined because I set up an initial value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

指尖上得阳光 2025-01-10 13:23:44

如果您将 availableFirms() 绑定到下拉列表,我假设您还将 firm() 绑定到同一个列表,以便当从下拉列表中选择另一个时列表中,firm() 会自动更新,并且所有绑定都会自动更新。

如果是这种情况,您根本不需要设置 firm() 因为它无论如何都会被设置为下拉列表中的第一个元素。

请参阅此处的示例 3:

http://knockoutjs.com/documentation/options-binding.html

var viewModel = {
    availableCountries : ko.observableArray([
        new country("UK", 65000000),
        new country("USA", 320000000),
        new country("Sweden", 29000000)
    ]),
    selectedCountry : ko.observable() // Nothing selected by default
};

像上面一样尝试一下,不要专门设置 firm() ,看看是否再次出错

If you're binding availableFirms() to a dropdownlist, I'm assuming you've also bound firm() to the same list so that when another is selected from the list, firm() gets automatically updated and all your bindings update automatically.

If this is the case, you do not need to set firm() at all as it will be set to the first element in the dropdownlist anyway.

See example 3 here:

http://knockoutjs.com/documentation/options-binding.html

var viewModel = {
    availableCountries : ko.observableArray([
        new country("UK", 65000000),
        new country("USA", 320000000),
        new country("Sweden", 29000000)
    ]),
    selectedCountry : ko.observable() // Nothing selected by default
};

Try it like above without specifically setting firm() and see if it errors again

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文