首页 文章

knockout-kendo通过计算的observable发出绑定

提问于
浏览
2

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

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

为了解决这个问题,我在以下主题中遵循了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元素重新绑定它们-evaluated和UI分别更新 .

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

2 回答

  • 4

    我来给你一些建议 . 尝试避免访问可观察值的属性,正如您所看到的,依赖性检测并不总是能够检测到依赖性 . 您应该创建一个计算的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

  • 2

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

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

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

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

相关问题