淘汰赛剑道通过计算可观察到的绑定问题 [英] knockout-kendo issues binding through computed observable

查看:85
本文介绍了淘汰赛剑道通过计算可观察到的绑定问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用敲除-kendo.js在敲除forEach模板中声明kendo dropdownlist控件,以便在将新项添加到敲除可观察数组中时,新的kendo下拉列表会在UI中呈现.

最初,我意识到我无法再将下拉列表的选定值绑定到下拉列表的指定数据"数组中的整个条目对象.

为克服此问题,我在以下主题中遵循了RP Niemeyer的建议: 设置下拉列表的绑定击倒物体

现在,这一切正常.很好.

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

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

原始小提琴(RP尼迈耶氏)

我的小提琴有问题

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

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.

我错过了什么吗?还是有一种更好的方法来实现这种链接下拉列表"行为(同时仍使用敲除模板和kendo下拉列表控件)?

解决方案

让我为您提供一些建议.如您所见,请尝试避免访问可观察值的属性,依赖关系检测将无法始终能够检测到依赖关系.您应该创建一个计算得到的可观察对象,为您进行访问.

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

更新了小提琴

I am attempting to use knockout-kendo.js to declare a kendo dropdownlist control in a knockout forEach template, so that as new items are added to the knockout observable array, new kendo dropdownlists are rendered in the UI.

Initially, I come to realize that I can no longer bind the dropdownlist's selected value to an entire entry object in my dropdownlist's specified 'data' array.

To overcome this issue, I followed the RP Niemeyer's suggestion in the following thread: Set the binding of a dropdown in knockout to an object

Now, this all works. Great.

My issue is when attempting to add second drop down list to the template, who's data is bound to an array property on the object being returned from the computed observable... (I need to chain the drop down lists so that the first displays all Students, second displays all classes for the student that is currently selected in the first drop down list, third displays all test grades for the class that is currently selected in the second drop down list, etc....)

I created a fiddle based on RP Niemeyer's original fiddle to demonstrate my issue:

Original Fiddle (RP Niemeyer's)

My Fiddle With Issues

I added the below lines to the fiddle:

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" }]) }
    ]);

Again, I was expecting that upon the selection changing in the first drop down list (causing selectedId to change, causing selectedChoice to change) would also cause any UI elements bound to 'selectedChoice' or any of selectedChoices' properties, to have their bindings re-evaluated and UI respectively updated.

Am I missing something? Or is there a better way to achieve this 'chaining of drop down list' behavior (while still utilizing a knockout template and kendo drop down list control)?

解决方案

Let me offer you some advice. Try to avoid accessing properties of an observable's value, as you can see, the dependency detection will not always be able to detect the dependency. You should create a computed observable which does the accessing for you.

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);
}

Then your bindings becomes:

<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

这篇关于淘汰赛剑道通过计算可观察到的绑定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆