Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
206 views
in Technique[技术] by (71.8m points)

javascript - Meteor 0.8 Blaze how to update rendered changes for Jquery plugins

My question is how to get 1 event or rendered callback when a group of elements are updated in the DOM? If I follow the link in the Blaze wiki https://github.com/avital/meteor-ui-new-rendered-callback this is not what I want. If I follow the second recommendation, I will get as many rendered calls as I have elements. And the parent element will only get 1 rendered callback on page load.

In my case, I'm using the Footable Jquery plugin to format a table. The initial load works fine, but if I change a filter variable in the Collection find, the DOM updates and no rendered is called again since Blaze only calls rendered once. I do not want to put the into another template, because that just means multiple calls to rendered and thus multiple calls to Footable when it only needs one for the entire table.

Any help is appreciated.

<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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The best solution would be to write a custom block helper. Lemme do it for you :)

Implementation

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();
    },
  });
});

Usage

Now, in your templates you can do something like:

<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>

Of course you should customize the behavior of the helper to your own needs.

Reflections

There is also another - more generic - solution that follows the pattern of how markdown helper is implemented here. However, I would not encourage to apply this strategy to your specific usecase.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...