Meteor 0.8 Blaze как обновить отрисованные изменения для плагинов JQuery

Мой вопрос: как получить 1 событие или обработанный обратный вызов, когда группа элементов обновляется в DOM? Если я перейду по ссылке в вики Blaze https://github.com/avital/meteor-ui-new-rendered-callback это не то, что я хочу. Если я последую второй рекомендации, я получу столько обработанных вызовов, сколько у меня элементов. А родительский элемент получит только 1 обработанный обратный вызов при загрузке страницы.

В моем случае я использую плагин Footable JQuery для форматирования таблицы. Начальная загрузка работает нормально, но если я изменяю переменную фильтра в поиске коллекции, DOM обновляется, и визуализация не вызывается снова, поскольку Blaze вызывает визуализацию только один раз. Я не хочу помещать его в другой шаблон, потому что это просто означает несколько вызовов для визуализации и, следовательно, несколько вызовов Footable, когда ему нужен только один для всей таблицы.

Любая помощь приветствуется.

<template name="customerData">
  <table class="table">
    {{#each dataRows}}
    <tr>
      <td>{{first_name}}</td>
      <td>{{last_name}}</td>
      <td>{{email}}</td>
     {{#each phones}}
        <td>{{phone}}</td>
     {{/each}}
    </tr>
    {{/each}}
  </table>
</template>

Template.customerData.rendered = function(){
  $(".table").footable();
}

Template.customerData.phones = function(){
    var result = [];

    _.each(this.phoneNumbers, function(element, index, list){
       result.push({ phone: element});
    });

return result;
}

person richStorm    schedule 01.04.2014    source источник
comment
взгляните на _.debounce ().   -  person user728291    schedule 02.04.2014
comment
@ user728291, это отличное предложение. Спасибо. В итоге я использовал _.debounce () в обработанном обратном вызове для строки и переместил строку html в свой собственный шаблон.   -  person richStorm    schedule 08.04.2014


Ответы (1)


Лучшим решением было бы написать собственный помощник блока. Дай мне сделать это за тебя :)

Реализация

UI.registerHelper('footableBody', function () {

  var dependency = new Deps.Dependency(),
      dataSource = this,
      handle, footable;

  return UI.Component.extend({
    render: function () {
      var self = this;
      return UI.Each(function () {
        return dataSource;
      }, UI.block(function () {
        dependency.changed();
        return self.__content;
      }));
    },
    rendered: function () {
      var $node = $(self.firstNode).closest('table');
      handle = Deps.autorun(function () {
        if (!footable) {
          $node.footable();
          footable = $node.data('footable');
        } else {
          footable.redraw();
        }
        dependency.depend();
      });
    },
    destroyed: function () {
      handle && handle.stop();
    },
  });
});

использование

Теперь в ваших шаблонах вы можете сделать что-то вроде:

<table class="table">
  <thead>
    ...
  </thead>
  <tbody>
  {{#footableBody dataRows}}
    <tr>
      <td>{{first_name}}</td>
      <td>{{last_name}}</td>
      <td>{{email}}</td>
      <td>{{phone}}</td>
    </tr>
  {{/footableBody}}
  </tbody>
</table>

Конечно, вы должны настроить поведение помощника под свои нужды.

Размышления

Существует также другое - более общее - решение, которое следует схеме реализации помощника markdown здесь. Однако я бы не рекомендовал применять эту стратегию к вашему конкретному варианту использования.

person Tomasz Lenarcik    schedule 01.04.2014
comment
Не могли бы вы указать на какую-нибудь документацию о том, как писать собственные компоненты, или хотя бы на несколько примеров? - person Andrew Mao; 02.04.2014
comment
@AndrewMao Я не знаю, есть ли это в документации, но отличный источник примеров - это исходный код встроенных пакетов ui и showdown (взгляните на реализации UI.Each, UI.If и UI.With и markdown). Вы также можете взглянуть на пакет blaze-layout от EventedMind - он устарел, но в любом случае является хорошим примером. Я также сделал несколько собственных, поэтому, если вы посмотрели пакеты mathjax, highlight или tags (в настоящее время ветки devel или blaze-), вы также можете найти что-то, что может вас заинтересовать. - person Tomasz Lenarcik; 02.04.2014
comment
@apendua Отличное решение! Спасибо. Тем не менее, я добавлю в смесь изящный шар. Если я звоню на _.each, скажем, по нескольким телефонным номерам, я не знаю, сколько их. Это решение возвращает первые 3 столбца с Footable, но столбцы с телефонными номерами отображаются после вашего dependency.changed () - person richStorm; 03.04.2014
comment
Принял решение. Я обновил вопрос с дополнительной информацией в моей ситуации. Извините, я не включил его с самого начала. Похоже, рендеринг срабатывает, когда данные возвращаются с сервера, но в моем случае мне нужно рендеринг для срабатывания, когда рендерится финальный ‹td›. - person richStorm; 03.04.2014
comment
@richStorm Я никогда не утверждал, что этого решения будет достаточно для всех целей :) Оно представляет собой только общую схему, которую вы, конечно же, должны адаптировать к вашим конкретным потребностям. - person Tomasz Lenarcik; 03.04.2014
comment
@richStorm К сожалению, похоже, что нет способа изменить это поведение. Вот почему мы используем dependency. Фактически, Deps.autorun будет запускаться повторно в первый раз точно после рендеринга последнего td. Мне это кажется разумным ... - person Tomasz Lenarcik; 03.04.2014
comment
@apendua Да, Deps.autorun будет запускаться после отображения td имени, фамилии и адреса электронной почты. Однако поведение Blaze, похоже, сначала обрабатывает рендеринг, исходящий от курсора, а затем сшивает вспомогательный метод (имеется в виду вспомогательный метод Template.customerData.phones). Так что я должен поместить Deps.changed () внутрь этого помощника? - person richStorm; 03.04.2014
comment
@richStorm Вы можете попробовать. Однако из того, что я видел в footable исходном коде, они требуют, чтобы количество столбцов было более или менее постоянным. Более конкретно, когда таблица инициализируется в первый раз, они ищут столбцы, определенные в <thead> (вы, вероятно, можете изменить это поведение, предоставив настраиваемый селектор, но я не уверен), и с этого момента добавление данных с большим количеством столбцов просто не сработает. На вашем месте я бы не стал связываться с количеством столбцов, а поместил бы все номера телефонов в одну ячейку. - person Tomasz Lenarcik; 03.04.2014