【问题标题】:knockout-kendo issues binding through computed observable淘汰赛-剑道通过计算的 observable 问题绑定
【发布时间】:2013-03-26 15:26:07
【问题描述】:

我正在尝试使用 knockout-kendo.js 在淘汰赛 forEach 模板中声明一个剑道下拉列表控件,以便在向淘汰赛可观察数组中添加新项目时,在 UI 中呈现新的剑道下拉列表。

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

为了克服这个问题,我在以下线程中遵循了 RP Niemeyer 的建议: Set the binding of a dropdown in knockout to an object

现在,这一切都奏效了。太好了。

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

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

Original Fiddle (RP Niemeyer's)

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。

我错过了什么吗?或者有没有更好的方法来实现这种“下拉列表链接”行为(同时仍然使用敲除模板和剑道下拉列表控件)?

【问题讨论】:

    标签: javascript knockout.js kendo-ui


    【解决方案1】:

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

    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 }" />
    

    updated fiddle

    【讨论】:

    • 这是最好的方法。作为解析绑定字符串的一部分而创建的依赖项目前在 Knockout-Kendo 中不会被跟踪。希望这可以改善,特别是如果/当我们解决这个问题时:github.com/SteveSanderson/knockout/issues/500
    【解决方案2】:

    这似乎是使用 Knockout 的 Kendo 的一个缺点。当 Kendo 计算 selectedChoice().shapes 时,它会保留它找到的数组,而不是保留整个表达式。如果您使用选项更新该特定数组,您可以在第二个下拉列表中看到它们。问题是当您更新selectedChoice 时,Kendo 不会将数据重新评估为新的shapes 数组。您可以在 this fiddle 中看到这种行为。

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

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

    您将看到第二个下拉列表更新。更改第一个下拉列表没有效果。你可以看到this fiddle Knockout without kendo 会重新评估整个表达式,正确更新第二个select 选项。

    【讨论】:

      猜你喜欢
      • 2020-05-30
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 2015-08-19
      • 2019-11-19
      相关资源
      最近更新 更多