2016-05-11 5 views
0

画像のようにカスケードリストボックスを作成する必要がありますが、各リストボックスは同じデータリストを使用しますが、フィルタは異なります。 enter image description here 私はthis codeを持っていますが、私は2つの選択肢でそれを行うことができますが、あなたが見ることができるように、私は2つの観測値を使って各選択値を読み込みます。 foreachバインドを使用してこれを作成する方法はありますか?foreachを使用して同じフィルタリングされたリストのカスケードリストボックス

var ViewModel = function() { 
 
    self = this; 
 
    self.family = ko.mapping.fromJS(data.family); 
 
    self.selected = ko.observable(); 
 
    self.selected2 = ko.observable(); 
 

 

 
    self.filteredFamily = ko.computed(function() { 
 
    var list = ko.utils.arrayFilter(self.family(), function(item) { 
 

 
     if (self.selected() == undefined) return; 
 
     return item.parent() === self.selected().name(); 
 
    }); 
 

 
    return list; 
 
    }); 
 
} 
 

 
var data = { 
 
    family: [{ 
 
    name: "John", 
 
    parent: null 
 
    }, { 
 
    name: "Mike", 
 
    parent: null 
 
    }, { 
 
    name: "Alice", 
 
    parent: "John" 
 
    }, { 
 
    name: "Paul", 
 
    parent: "John" 
 
    }] 
 
}; 
 
var viewModel = new ViewModel(); 
 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<select data-bind="options: family, optionValue: name,optionsText: 'name',value:selected, optionsCaption: 'Choose...'"></select> 
 
<select data-bind="options: filteredFamily, optionValue: name,optionsText: 'name',value:selected2, optionsCaption: 'Choose...'"></select>

[UPDATED]

、私は必要な私は私の質問はよく策定されなかったと思います申し訳ありませんが、その私はリストボックスで何かを選択し、次の更新は、彼のデータと最後のlisboxのデータ。

答えて

0

私はそれを行う方法を見つけました。ここで私がやっているものです:

var ViewModel = function() { 
 
    self = this; 
 
    self.family = ko.mapping.fromJS(data.family); 
 
    self.selected = ko.observable(); 
 

 

 
    self.filteredFamily = ko.computed(function() { 
 
    var list = ko.utils.arrayFilter(self.family(), function(item) { 
 
     debugger; 
 
     if (self.selected() == undefined) return; 
 
     return item.parent() === self.selected().name(); 
 
    }); 
 
    debugger; 
 
    return list; 
 
    }); 
 
} 
 

 
var data = { 
 
    family: [{ 
 
    name: "John", 
 
    parent: null 
 
    }, { 
 
    name: "Mike", 
 
    parent: null 
 
    }, { 
 
    name: "Alice", 
 
    parent: "John" 
 
    }, { 
 
    name: "Paul", 
 
    parent: "John" 
 
    }] 
 
}; 
 
var viewModel = new ViewModel(); 
 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<select data-bind="options: family, optionValue: name,optionsText: 'name',value:selected, optionsCaption: 'Choose...'"></select> 
 
<select data-bind="options: filteredFamily, optionValue: name,optionsText: 'name',value:selected()[1], optionsCaption: 'Choose...'"></select>

0

しかし、foreachは(観測可能な)配列を必要とし、別のビューモデルで "ウィジェット"コードをカプセル化することをお勧めします。ここで素朴なセットアップです:

var SelectionViewModel = function(baseOptionsObsArray, filter) { 
 
    var self = this; 
 
    
 
    self.filteredOptions = ko.computed(function() { 
 
    var val = ko.utils.unwrapObservable(filter.val); // Allow observable and plain property 
 
    return baseOptionsObsArray().filter(function(opt) { 
 
     return ko.utils.unwrapObservable(opt[filter.prop]) === val; 
 
    }); 
 
    }); 
 
    
 
    self.filter = filter; 
 
    
 
    self.selected = ko.observable(); 
 
}; 
 

 
var ViewModel = function(data) { 
 
    var self = this; 
 
    self.family = ko.mapping.fromJS(data.family); 
 
    self.selectables = ko.observableArray([ 
 
    new SelectionViewModel(self.family, { name: "No Parent", prop: "parent", val: null }), 
 
    new SelectionViewModel(self.family, { name: "Parent is John", prop: "parent", val: "John" }), 
 
    new SelectionViewModel(self.family, { name: "Has a pet", prop: "hasPet", val: true }), 
 
    new SelectionViewModel(self.family, { name: "Name is Alice", prop: "name", val: "Alice" }), 
 
    ]); 
 
}; 
 

 
var data = { 
 
    family: [{ name: "John", parent: null, hasPet: true }, 
 
      { name: "Mike", parent: null, hasPet: true }, 
 
      { name: "Alice", parent: "John", hasPet: false }, 
 
      { name: "Paul", parent: "John", hasPet: true } 
 
    ] 
 
}; 
 

 
ko.applyBindings(new ViewModel(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<!-- ko foreach: selectables --> 
 
<span data-bind="text: filter.name"></span> 
 
<select data-bind="options: filteredOptions, 
 
        optionValue: name, 
 
        optionsText: 'name', 
 
        value: selected, 
 
        optionsCaption: 'Choose...'"></select> 
 
<hr> 
 
<!-- /ko -->

あなたが簡単に読者に運動して残っているなど、ワイルドカード、否定、とのより高度なフィルタリングのようなものを追加することができます。

どのような場合でも、あなたの質問(フィルタリングされたオプションリストで10個の選択肢を簡単に作成できるようにする方法)が回答されていると思います。一方


あなたが選択ボックスのドリルダウンスタイルのセットのためのより多くのを探しているなら、私はまだ別々のビューモデルと巣それを使用することをお勧め。例えば:

var SelectionViewModel = function(parent, everyone) { 
 
    var self = this; 
 
    
 
    self.selection = ko.observable(); 
 
    
 
    self.filteredOptions = everyone().filter(function(p) { 
 
    console.log(p); 
 
    if (!parent) { return !p.parent(); } 
 
    return p.parent() === parent.name(); 
 
    }); 
 
    
 
    self.subSelection = ko.computed(function() { 
 
    if (!self.selection()) { return null; } 
 
    return new SelectionViewModel(self.selection(), everyone); 
 
    }); 
 
}; 
 

 
var ViewModel = function(data) { 
 
    var self = this; 
 
    self.everyone = ko.mapping.fromJS(data.family); 
 
    self.familyHead = ko.observable(new SelectionViewModel(null, self.everyone)); 
 
}; 
 

 
var data = { 
 
    family: [{ name: "John", parent: null }, 
 
      { name: "Mike", parent: null }, 
 
      { name: "Alice", parent: "John" }, 
 
      { name: "Graaw", parent: "John" }, 
 
      { name: "Paul", parent: "John" }, 
 
      { name: "Marc", parent: "Alice" }, 
 
      { name: "Fika", parent: "Alice" }, 
 
      { name: "Eric", parent: "Marc" } 
 
    ] 
 
}; 
 

 
ko.applyBindings(new ViewModel(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> 
 

 
<script type="text/html" id="selectable"> 
 
<select data-bind="options: filteredOptions, 
 
        optionValue: name, 
 
        optionsText: 'name', 
 
        value: selection, 
 
        optionsCaption: 'Choose...'" 
 
     size="5"></select> 
 
<!-- ko with: subSelection --> 
 
<!-- ko template: 'selectable' --><!-- /ko --> 
 
<!-- /ko --> 
 
</script> 
 

 
<!-- ko template: { data: familyHead, name: 'selectable' } --><!-- /ko -->

+0

申し訳ありません@Jeroen、私は私の質問はよく策定されなかったと思い、私が必要とする、私はリストボックスで何かを選択し、次の更新彼のデータ最後のlisboxのデータと比較します。 – Guto

関連する問題