2013-03-26 39 views
2

我正尝试使用knockout-kendo.js在淘汰赛forEach模板中声明一个kendo dropdownlist控件,以便在新项目添加到淘汰赛可观察数组中时,新的kendo dropdownlist是在UI中呈现。knockout-kendo通过计算可观察性发布绑定

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

为了克服这个问题,我也跟着RP尼迈耶在以下螺纹的建议: Set the binding of a dropdown in knockout to an object

现在,这所有的作品。大。

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

我创建了一个基于RP尼迈耶的原始小提琴小提琴来证明我的问题:

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更改)也会导致任何UI元素bou找到'selectedChoice'或任何selectedChoices的属性,以重新评估其绑定并分别更新UI。

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

回答

2

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

打开JS控制台,上下文设置为小提琴(默认为在Chrome`的top frame,并运行此:

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

你会看到第二个下拉更新更​​改第一个下拉列表没有按。没有影响,你可以看到在this fiddle没有剑道的淘汰赛重新评估整个表达式,正确更新第二个select选项。

4

让我给你提供一些建议。尽量避免访问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

+0

这是最好的一段路要走。在Knockout-Kendo中,作为解析绑定字符串的一部分创建的依赖关系当前不会被跟踪。希望这可以改善,特别是当我们解决这个问题时:https://github.com/SteveSanderson/knockout/issues/500 – 2013-03-26 17:26:35