2

私は質問/回答モデルに取り組んでおり、同じデータを含む複数のドロップダウンがあります(必要に応じて回答のバンク)。ここでのビジネスロジックは、誰かが質問に対する回答を選択すると、その回答は1回しか使用できず、他の質問には使用できないというものです。

そのため、すべてのドロップダウンを、回答を含む単一のobservableArrayにバインドして、ドロップダウンにすべて同じオプションが含まれるようにする方法を見つけました。私がやりたいのは、1つのドロップダウン(多くのうち)の現在の値をサブスクライブし、それらに関連付けられている他のすべてのドロップダウンから選択した値を削除することです。Knockoutを使用して、ビュー内の変化する値にコールバック関数をサブスクライブすることができました。

コールバック関数で、observableArrayのメソッドを使用してobservableArrayから回答を削除すると機能することがわかりましたremoveが、残念ながら、現在選択されている回答がすべてのドロップダウン(選択されたものを含む)から削除されます。プッシュコマンドで元に戻してみましたが、それでも問題が発生します。更新を希望どおりに分離できないようです。

以前にKnockoutを使用してこのようなものを実装した人はいますか?どんな助けやアドバイスもいただければ幸いです。

4

2 に答える 2

4

アイテムを削除するとオプションの配列にバインドされるため、オプションのバインドはこれを正しく反映します。バインドする選択ボックスごとに計算されたものを使用して、独立した仮想リストを作成できます。

var viewModel = function(data) {
   var self = this;
   this.values = ko.observableArray([ "option 1", "option 2", "option 3"]);
   this.selected = [
       new ko.observable(),
       new ko.observable(),
       new ko.observable()
   ]

   this.remaining = function (current) {
       var selected = ko.toJS(self.selected),
           currentValue = ko.utils.unwrapObservable(current);
       var result = ko.utils.arrayFilter(self.values(), function (option) {
           return option == currentValue || selected.indexOf(option) === -1;
       });
       return result;            
   };

   this.values1 = ko.computed(function () {
      return self.remaining(self.selected[0]);
   });
   this.values2 = ko.computed(function () {
      return self.remaining(self.selected[1]);
   });
   this.values3 = ko.computed(function () {
      return self.remaining(self.selected[2]);
   });
};

ko.applyBindings(new viewModel());

http://jsfiddle.net/madcapnmckay/6uWEu/2/

編集

上記の仕組みは次のとおりです。最初に値を選択したときに他の値を更新できるように、各選択をそれ自体のオブザーバブルにバインドする必要があります。同じリストにバインドして、値が選択されるたびにリストから削除すると、選択したばかりの値も削除され、KOはそれに応じて選択要素を更新するため、完全に壊れます。

上記のコードは、それぞれを順番にフィルタリングすることでこれを解決します。各ドロップダウンを独自の計算されたオブザーバブルにリダイレクトしました。これらの計算されたオブザーバブルは、values配列をループし、現在選択されている値ではない選択されたものをフィルターで除外するフィルター関数を呼び出すだけです。

したがって、すべての選択を解除して開始すると、最初の選択で「オプション1」が選択され、values1、values2、values3が計算され、KOによって自動的に再計算されます。例としてvalues1を取り上げると、

self.remaining("option 1");

values2 * values3も残りを呼び出しますが、選択されていないため、未定義です。

self.remaining(null);

値の配列は、選択されておらず、現在の値ではないオプションにフィルターされます。したがって、remainingへの最初の呼び出しは結果になり[ "option 1", "option 2", "option 3"]ます。残りの2番目と3番目の呼び出しは、結果になり[ "option 2", "option 3"]ます。

最初の選択を解除すると、同じ操作が実行され、すべてのオプションが返されます。

お役に立てれば。

于 2012-05-15T16:23:57.897 に答える
0

同様のことをしなければならなかったときIsSet、アイテムにプロパティがあり、2つの計算されたオブザーバブルがありました。1つは設定されている値用で、もう1つは設定されていない値用です。

var ViewModel = function(data) {
    this.self = this;
    self.originalList = ko.observableArray(data.list);
    self.selectedItems = ko.computed(function() {
        return ko.utils.arrayFilter(function(item) { return item.IsSet(); });
    });
    self.unselectedItems = ko.computed(function() {
        return ko.utils.arrayFilter(function(item) { return !item.IsSet(); });
    });
};
于 2012-05-15T19:47:33.413 に答える