击倒剑道问题绑定通过计算观察

knockout-kendo issues binding through computed observable

本文关键字:计算 观察 绑定 问题      更新时间:2023-09-26

我试图使用knockout-kendo.js在knockout forEach模板中声明一个剑道下拉列表控件,这样当新的项目被添加到knockout可观察数组中时,新的剑道下拉列表就会在UI中呈现。

最初,我意识到我不能再将下拉列表的选定值绑定到下拉列表指定的'data'数组中的整个条目对象。

为了克服这个问题,我在以下线程中遵循了RP Niemeyer的建议:将knockout中的下拉列表绑定到一个对象

现在,这一切都工作了。很好。

我的问题是,当试图添加第二个下拉列表到模板,谁的数据被绑定到数组属性的对象从计算的可观察对象返回…(我需要链接下拉列表,以便第一个显示所有学生,第二个显示当前在第一个下拉列表中选择的学生的所有班级,第三个显示当前在第二个下拉列表中选择的班级的所有考试成绩,等等....)

我根据RP Niemeyer的原始小提琴创建了一个小提琴来演示我的问题:

原小提琴(RP尼迈耶)

My Fiddle With Issues

我在小提琴中添加了以下行:

HTML:

<input data-bind="kendoDropDownList: { dataTextField: 'caption', dataValueField: 'id', data: selectedChoice().shapes, value: selectedShapeId }" />

JS:

this.choices = ko.observableArray([
        { id: "1", name: "apple", shapes: ko.observableArray([ { id: "5", caption: "circle" }, { id: "6", caption: "square" }]) },
        { id: "2", name: "orange", shapes: ko.observableArray([ { id: "5", caption: "circle" }]) },
        { id: "3", name: "banana", shapes: ko.observableArray([ { id: "5", caption: "circle" }, { id: "6", caption: "square" }, { id: "7", caption: "triangle" }]) }
    ]);

再一次,我期望在第一个下拉列表中的选择改变时(导致selectedId改变,导致selectedChoice改变)也会导致绑定到'selectedChoice'或任何selectedChoices'属性的任何UI元素重新评估其绑定并分别更新UI。

我错过了什么吗?或者是否有更好的方法来实现这种"下拉列表链"的行为(同时仍然使用击倒模板和剑道下拉列表控件)?

让我给你一些建议。尽量避免访问可观察对象值的属性,正如你所看到的,依赖检测并不总是能够检测到依赖。你应该创建一个可计算的可观察对象来为你进行访问。

var ViewModel = function () {
    // ...
    this.selectedChoice = ko.computed(function () {
        var id = this.selectedId();
        return ko.utils.arrayFirst(this.choices(), function(choice) {
           return choice.id ===  id;
        });
    }, this);
    this.selectedChoiceShapes = ko.computed(function () {
        var selectedChoice = this.selectedChoice();
        return selectedChoice && selectedChoice.shapes;
    }, this);
}

那么你的绑定变成:

<input data-bind="kendoDropDownList: {
                      dataTextField: 'name',
                      dataValueField: 'id',
                      data: choices,
                      value: selectedId }" />
<input data-bind="kendoDropDownList: {
                      dataTextField: 'caption',
                      dataValueField: 'id',
                      data: selectedChoiceShapes,
                      value: selectedShapeId }" />

更新小提琴

这似乎是剑道使用击倒的缺点。当Kendo计算selectedChoice().shapes时,它保留找到的数组,而不是保留整个表达式。如果您使用选项更新特定数组,您可以在第二个下拉列表中看到它们。问题是,当你更新selectedChoice剑道不重新评估数据到新的shapes数组。您可以在此提琴中看到此行为。

打开JS控制台,将上下文设置为fiddle(在Chrome中默认为top frame),然后运行这个:

window.vm.choices()[1].shapes.push({"id": "6", "caption" : "Thing"})

您将看到第二个下拉更新。改变第一个下拉菜单没有效果。您可以看到,在这个没有剑道的Knockout中,重新计算了整个表达式,正确地更新了第二个select选项。