Knockout.js - 禁用,而不是隐藏,级联选择?

时间:2013-02-08 12:06:23

标签: knockout.js cascadingdropdown

我使用Knockout创建了多个级联选项,使用的灵感来自this questionjsFiddle({{3}} - 在帖子底部的代码中接受的答案)。

效果很好,但是我想在孩子不可用时选择禁用,而不是完全隐藏它们。

这有一个简单的选择吗?

隐藏行为似乎是由'with'绑定驱动的,但这似乎是数组链接的必要条件。

var mainViewModel = null;

var mainViewModelData = {
    "RequestName": "test Name",
    "BusinessLines": [{
        "Id": 1,
        "Title": "Retail",
        "Clusters": [{
            "Id": 1,
            "Title": "Corporate si Trezorerie"},
        {
            "Id": 2,
            "Title": "Good Bee"},
        {
            "Id": 3,
            "Title": "Leasing"}]},
    {
        "Id": 2,
        "Title": "Corporate",
        "Clusters": [{
            "Id": 1,
            "Title": "REM"},
        {
            "Id": 2,
            "Title": "BCR Procesare"},
        {
            "Id": 3,
            "Title": "Erste Asset Management"}]}],
    "SelectedBusinessLine": null,
    "SelectedCluster": null,
    "RequirementHighLevelDescription": null,
    "Revenues": 0,
    "Savings": 0,
    "PreventedLosses": 0
};

mainViewModel = ko.mapping.fromJS(mainViewModelData);

ko.applyBindings(mainViewModel);

<div>         
<table>            
  <tr>      
    <td>      
        Business Line    
      </td>
      <td>
          <select data-bind="options: BusinessLines,                                                         optionsText: 'Title',                                                           value: SelectedBusinessLine,  
                             optionsCaption: 'Select Business Line..'">
                 </select>           
             </td>
    </tr>

    <tr data-bind="with: SelectedBusinessLine">
        <td>
            Cluster
        </td>
        <td>              <select data-bind="options: Clusters,                                        optionsText: 'Title',                                                        value: $root.SelectedCluster,                                                        optionsCaption: 'Select Cluster..'">   
            </select>
        </td>
    </tr>
    </table>
</div>

2 个答案:

答案 0 :(得分:1)

这不是那么微不足道,但可能......

首先,您要创建计算的observable,它将每个BusinessLine的所有集群与parent属性合并,以保留集群的父BusinessLine对象:

mainViewModel.AllClusters = ko.computed(function(){
    var result = [];
    ko.utils.arrayForEach(this.BusinessLines(), function(line){
        ko.utils.arrayForEach(line.Clusters(), function(cluster){
            result.push({ parent: line, Title: cluster.Title() });
        });
    });
    return result;
}, mainViewModel);

然后有必要创建新类型的绑定enabledOptions,它将根据<option/>属性比较结果为每个集群parent设置/删除“disabled”属性:

ko.bindingHandlers.enabledOptions = {
    update: function(element, valueAccessor, allBindings) {

        var options = element.getElementsByTagName('option'),
            parent = ko.utils.unwrapObservable(valueAccessor()),
            // delta is neccessary to strip select's caption if it exists
            delta = allBindings().optionsCaption ? 1 : 0;

        for (var i = delta; i < options.length; i++) {
            var cluster = mainViewModel.AllClusters()[i - delta];
            cluster.parent == parent
            ? options[i].removeAttribute('disabled')
            : options[i].setAttribute('disabled', 'disabled')
        }

    }
}

最后删除你提到的with绑定。

结果你会得到这样的结果:http://jsfiddle.net/ostgals/x2qMg/28/

答案 1 :(得分:0)

删除with绑定,并将options绑定绑定到SelectedBusinessLine().Clusters

然后使用disable绑定禁用选择。