0

私はこれを考えすぎているかもしれませんが、私がやろうとしているのは、関数にバインドされたクリック イベントから observableArray を作成することです。基本的に、ボタンをクリックすると、ページの後半でループevent.target.html()で使用できるオブザーバブルに基づいて結果をフィルタリングし、作成する必要があります。foreach

まず、ボタンがあります。

<button data-bind="click: getData">Button Text</button> 

ボタンテキストに基づいて結果をフィルタリングする関数

self.filterFunction = function(x) {
      // do things here
      return (obj);
}

Click はgetData関数にバインドされ、クリックから DOM 要素を呼び出しfilterFunctionて監視可能な配列を作成します

self.getData = function(item, event) {
      viewModel.myFilteredData = ko.observableArray(self.filterFunction($(event.target).html()));  

}

そして、ループしますmyFilteredDataが、惨めに失敗します。

<!-- ko foreach: myFilteredData -->
       // Generate HTML here
<!-- /ko -->

私は論理が苦手で、もっと効率的な方法があると何かが教えてくれます。また、ボタンがクリックされる前に、最初のページの読み込み時に HTML を生成できるように、myFilteredDataいくつかの pre-set に基づいて事前入力する方法を見つけたいと思います。Button Text

ありがとうございました。

4

3 に答える 3

2

おそらく、あなたが抱えている問題はforeach、クリック後に生成したものとは異なる監視可能な配列にバインディングがバインドされていることです。このように考えてください。このビューモデルを考えると:

{
    myFilteredData: ko.observableArray()
}

...ko.applyBindingsこれが発生すると、Knockoutko.observableArrayは更新のためにこれをサブスクライブし、(現在は空の) 配列をループします。

これで、クリック ハンドラーが発生します。

viewModel.myFilteredData = ko.observableArray(self.filterFunction($(event.target).html()));  

監視可能な配列が変更されていないため、上記で確立されたサブスクリプションはトリガーされません。代わりに、別のものに置き換えました。残念ながら、Knockout は新しいものについて知りません。

配列を新しいものに置き換える代わりに、既存の配列に新しいデータを入力することをお勧めします。

viewModel.myFilteredData(self.filterFunction($(event.target).html()));  
于 2013-06-19T23:52:45.033 に答える
2

ソレファルド、これを行うためのより良い方法は間違いなくあります.

まず、独自の「フィルター」オブジェクトの配列をビュー モデルに追加し、ko.computed を追加して、フィルター処理されたデータを提供します。フィルター ボタンを「フィルター」オブジェクトの配列にバインドします。このようなもの:

var viewModel = function(){
    var self = this;
    self.filters = [
        {buttonText:'Button Text', filterKey:'filterKeyOne'},
        {buttonText:'Other Button Text', filterKey:'filterKeyTwo'}
    ];
    self.selectedFilterKey = ko.observable('none');
    self.setFilter = function(){...}

    self.data = ko.observableArray([...]);
    self.filteredData = ko.computed(function(){...});
}

次のようにバインドします。

<div data-bind="foreach: filters">
    <button data-bind="click : $parent.setFilter, text: buttonText"></button>
</div>
<div data-bind="foreach: filteredData">
    ...
</div>

Knockout にフィルター ボタンのクリック バインディングを行わせることで、"runFilter" 関数の最初のパラメーターとしてフィルター オブジェクト全体を取得できます。次に、フィルター ボタンのクリック ハンドラー (この例では "setFilter") を次のように実装できます。

self.setFilter = function(filterItem){
   self.selectedFilterKey(filterItem.filterKey);
};

"selectedFilterKey" をオブザーバブルにすることで、filteredData を ko.computed として実装できます。これは、次のように、"selectedFilterKey" が変更されたときに ui を自動的に更新します。

...
self.filteredData = ko.computed(function(){
    //pick the right filter function
    var filterFunction = filterOne;//assign the default filter function
    switch(self.selectedFilterKey()){
        case 'filterKeyOne':
            filterFunction = self.filterOne;//your first filter
        break;
        case 'filterKeyTwo':
            filterFunction = self.filterTwo;//your second filter
        break;
    }
    return ko.utils.arrayFilter(self.data(), function(item){        
        //return true if item passes filter
        return filterFunction(item);
    });
});
...

機能的アプローチ

より関数的なプログラミング アプローチを使用する場合は、フィルター オブジェクトでフィルター関数を定義してみてください。

self.filters = [
    {buttonText:'Button Text', filterFunction:function(item){...}},
    {buttonText:'Other Button Text', filterFunction:function(item){...}}
];

キーではなく、選択した機能を保存します

self.setFilter = function(filterItem){
   self.selectedFilterFunction(filterItem.filterFunction);
};

switchステートメントをスキップします

...
self.filteredData = ko.computed(function(){
    return ko.utils.arrayFilter(self.data(), function(item){        
        //return true if item passes filter
        return self.selectedFilterFunction()(item);
    });
});
...

詳しくは

この並べ替えの方法について詳しく知りたい場合は、こちらのブログで読むことができます: http://ryanrahlf.com/sorting-tables-by-column-header-with-knockout-js/

これが役立つことを願っています!

于 2013-06-20T00:00:46.690 に答える