0

に表示したいアイテムの長いリストがあります<ul>。「フィルター」入力を追加したいので、ユーザーはアイテムのリストをフィルターに一致するものに絞り込むことができます。

私のコントローラーにはfilter小道具とlist配列が含まれています:

function Ctrl() {
    this.filter = m.prop('');
    this.list = [];
}

updateコントローラーにメソッドを追加しました。このメソッドは、filter小道具を見て、list配列の内容を更新します。

Ctrl.prototype.update = function (value) {
    var _this = this;
    if (this.filter()) {
        searchItems(this.filter(), function (items) {
          _this.list = items;
        });
    } else {
        this.list = [];
    }
};

list最後に、ビューは配列を反復処理し、アイテムをレンダリングします。さらに、プロパティにバインドされた入力を上部に表示しますfilter

var view = function (ctrl) {
    return m('#content', [
        m('input', { 
             oninput: m.withAttr("value", ctrl.filter), 
             value: ctrl.filter() 
        }),
        m('ul', [
            ctrl.list.map(function (item, idx) {
                return m('li', m('span', item.getName()));
            })
        ])
    ]);
};

私の質問は、値が変更されupdateたときに関数を起動して、更新されたアイテムのリストを取得する方法です。filter

oninput2 つのイベントを配置する必要がありますか? 更新するfilterものと起動するものupdate

単一のイベントを使用して、関数内のプロパティoninputを更新する必要がありますか?filterupdate

他に何か?

4

1 に答える 1

0

m.withAttr を使用する場合、イベント ハンドラーが起動すると (oninput)、要素の属性 (値) を取得し、それを関数 (ctrl.filter) である 2 番目の引数に渡すということです。 )。現在の一連の出来事:

  1. フィルター プロパティが更新される
  2. ミスリル再描画

あなたがしたいことは、(ゲッター/セッター ctrl.filter 関数の代わりに)更新関数を呼び出し、それをバインドして、関数で適切なコンテキストを保持できるようにすることです。

m('input', {
  oninput: m.withAttr("value", ctrl.update.bind(ctrl)), 
  value: ctrl.filter() 
}),

次に、更新関数で値が関数に渡され、そこで設定できます。

Ctrl.prototype.update = function (value) {
  this.filter(value);
  ...

さてどうなるか:

  1. ctrl.filter プロパティが更新される
  2. ctrl.list は ctrl.filter に基づいてフィルタリングされます
  3. ミスリル再描画

これを処理する別の方法は、コントローラー/モデルに「リスト」プロパティを持たず、代わりにビューがフィルターされたリストを取得できるようにすることです。結局のところ、実際に変更されているのは 1 つだけです。それは「フィルター」プロパティです。フィルタリングされたリストはそれから派生したものであるため、コントローラーに別のプロパティを作成することで、同じ状態を効果的に複製しています。

さらに、 m.withAttr('value', ctrl.filter) を保持して、その単純さから利益を得ることができます。

何かのようなもの:

var filteredItems = ctrl.getFilteredItems();
var view = function (ctrl) {
    return m('#content', [
        m('input', { 
             oninput: m.withAttr("value", ctrl.filter), 
             value: ctrl.filter() 
        }),
        m('ul', [
            filteredItems.map(function (item, idx) {
                return m('li', m('span', item.getName()));
            })
        ])
    ]);
};
于 2015-12-08T08:19:44.423 に答える