【问题标题】:Meteor 0.8 Blaze how to update rendered changes for Jquery pluginsMeteor 0.8 Blaze 如何更新 Jquery 插件的渲染更改
【发布时间】:2014-05-12 11:01:35
【问题描述】:

我的问题是如何在 DOM 中更新一组元素时获取 1 个事件或渲染回调?如果我点击 Blaze wiki https://github.com/avital/meteor-ui-new-rendered-callback 中的链接,这不是我想要的。如果我遵循第二个建议,我将获得与元素一样多的渲染调用。并且父元素只会在页面加载时获得 1 个渲染回调。

在我的例子中,我使用 Footable Jquery 插件来格式化表格。初始加载工作正常,但如果我更改 Collection 查找中的过滤器变量,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;
}

【问题讨论】:

  • 看看_.debounce()
  • @user728291 这是一个很好的建议。谢谢你。我最终在行的渲染回调中使用 _.debounce() 并将行 html 移动到它自己的模板中。

标签: javascript jquery meteor footable meteor-blaze


【解决方案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 helper 如何实现here 的模式。但是,我不鼓励将此策略应用于您的特定用例。

【讨论】:

  • 您是否介意指出一些关于如何编写自定义组件的文档,或者至少是一些示例?
  • @AndrewMao 我不知道它是否在文档中,但是示例的重要来源是内置uishowdown包的源代码(看看@ 987654327@、UI.IfUI.Withmarkdown 实现)。您还可以查看 EventedMindblaze-layout 包 - 它已被弃用,但无论如何它都是一个很好的例子。我自己也做了几个,所以如果你查看mathjaxhighlighttags 包(目前为develblaze- 分支),你可能还会发现一些你可能感兴趣的东西。
  • @apendua 很好的解决方案!谢谢你。但是,我会在混合中扔一个曲线球。如果我打电话给“_.each”,让我们说多个电话号码,我不知道有多少。此解决方案使用 Footable 很好地返回前 3 列,但电话号码列在您的“dependency.changed()”之后呈现
  • 接受了解决方案。我在我的情况下使用附加信息更新了问题。对不起,我一开始就没有包括它。当数据从服务器返回时,看起来渲染正在触发,但在我的情况下,我需要在渲染最终 时触发。
  • @richStorm 我从来没有声称这个解决方案对所有用途都足够好 :) 它只提供了一个通用方案,您当然应该根据您的特定需求“量身定制”。
猜你喜欢
相关资源
最近更新 更多
热门标签