2015-12-07 6 views
0

У меня есть длинный список предметов, которые я хочу показать в <ul>. Я хочу добавить вход «фильтр», чтобы пользователь мог сузить список элементов до тех, которые соответствуют фильтру.Как создать зависимость с Mithril.js?

Мой контроллер содержит 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 изменений, так что я получаю обновленный список элементов?

Должен ли я разместить два события oninput? Один для обновления filter и один для стрельбы update?

Следует ли использовать одно событие oninput и обновить свойство filter в пределах его функции update?

Что-нибудь еще?

+1

Вы должны взглянуть на примере, приведенном в документе: http://lhorie.github.io/mithril-blog/organizing-components.html Это объясняет точно, что вы делаете: фильтрация списка. – fluminis

ответ

0

Когда вы используете m.withAttr, вы говорите, что когда обработчик события срабатывает (oninput), вы берете некоторый атрибут элемента (значения) и передаете его в свой второй аргумент, который является функцией (ctrl.filter). Ваша текущая последовательность событий:

  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. мифрил перерисовывает

другой способ справиться с этим состоит в том, чтобы не иметь никакого свойства «списка» в вашем контроллере/модели, но чтобы вместо этого просмотр захватил отфильтрованный список. В конце концов, только одна вещь действительно меняется, и это свойство «фильтр». Отфильтрованный список получается из этого, поэтому, создавая другое свойство на контроллере, вы фактически дублируете одно и то же состояние.

Кроме того, вы можете сохранить m.withAttr ('значение', 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())); 
      }) 
     ]) 
    ]); 
}; 
+0

Благодарим вас за ответ. Однако ваш первый пример делает 'filter' зависимым от' update', а не наоборот. Итак, если я изменил значение 'filter' где-то еще ниже в коде, значения' list' не будут обновляться Ваш второй пример немного лучше в моем случае, но он не позволяет мне построить список элементов, содержащих метаданные. Он связывает меня с использованием данных, предоставленных источником (ajax get или что-то еще). – miniml

+0

Хм, я бы порекомендовал вам прочитать документы на несколько подробнее, в частности, предоставил ссылку fluminus: http://lhorie.github.io/mithril-blog/organizing-components.html – dcochran

+0

Вы правы, что список не будет обновите, если вы только обновили фильтр, вам придется вызвать функцию обновления. Вот почему я не рекомендовал дублировать состояние и просто использовать фильтр для фильтрации списка в представлении. Вот что делает мифриловый пример в этой ссылке. И вы все еще можете «создать список элементов, содержащих метаданные», - вы просто напишете эту функциональность в «getFilteredItems». – dcochran