【问题标题】:Meteorjs: How to know if template is re rendered?Meteorjs:如何知道模板是否被重新渲染?
【发布时间】:2015-02-14 17:11:04
【问题描述】:

我有这个代码:

Template.temp.rendered = function () {
    console.log('temp rendered');
}

仅在网站初始化时记录。

但我会这样做:

more = function () {
    Meteor.subscribe('Videos', Session.get('more_info'));
}

当我调用 more();即使模板 dom 使用新文档更新,它也不会记录“临时渲染”。 还尝试了类似的东西:

Template.temp.rerendered = function () {
    console.log('temp re rendered');
}

它不起作用; 我如何知道 A 模板是否被重新渲染?

目前我正在做这样的事情

$('#list').bind("DOMSubtreeModified",function(){
    console.log('template modified'}
    //this logs like 200 times, every time the template is re rendered
)

流星的方式怎么办?

列表模板:

<template name="list">
    {{#each list}}
        <a id="{{_id}}" href="/{{category}}/{{_id}}" title="{{vTitle}}">
            {{vTitle}}
        </a>
    {{/each}}
</template>

助手:

Template.list.helpers({
  list : function () {
     return Videos.find({},{sort : {date : -1}});
  }
})

试过(不工作):

Template.list.rendered = function () {    
  this.autorun(function() {
    Videos.find();
    console.log('template re rendered');
  });
}

首选解决方案(来自@richsilv):

Template.list.rendered = function () {    
  this.autorun(function() {
    Videos.find().count();
    console.log('template re rendered');
  });
}

如果您每次渲染模板时都需要调用一个函数并且不想注册自动运行,那么@Peppe L-G 的解决方案也很好。

【问题讨论】:

    标签: templates dom meteor rerender


    【解决方案1】:

    是的,当模板最初呈现时,rendered 回调是 only fired once,而不是由于它所依赖的计算无效而更改时。

    Meteoric 做事的方法是在渲染的回调中添加一个this.autorun,它依赖于导致模板重新渲染的同一件事(即Videos 集合上的find,或其他)。你就是这样:

    1. 将您的反应性与数据源而非 DOM 联系起来,这除了从概念角度更明智之外,还意味着您不会在每次模板发生任何更改时都运行大量不必要的计算,即如果它依赖于多个数据源,则非常重要(如有必要,您可以为每个源设置不同的autorun)。
    2. 仍然利用模板的能力来停止 autorun 块被拆除时在 this 下声明的块,这消除了手动停止它们以避免加载浮动、未使用的自动运行占用 CPU 和内存的需要.

    【讨论】:

    • 我的意思是在加载后显示图像。如果不存在,则无法将此功能添加到图像中。这就是为什么我需要这个自动运行。顺便说一句,我尝试像这样添加 this.autorun: Template.list.rendered = function () { console.log('template rendering'); this.autorun;}
    • this.autorun 只是模板回调中Tracker.autorun 的代理,因此它会自动被拆除 - 您仍然必须将要运行的函数作为参数传递。
    • 要让它触发,你必须让它依赖于数据源。如果那是more_info Session 变量,您需要在传递给自动运行的函数中执行Session.get('more_info') inside,以便 Meteor 知道在该变量的结果发生变化时重新运行它。如果您更愿意让它依赖于Videos.find(),则类似。
    • 如果您需要更多信息,请查看this
    • 谢谢,这正是我想要的。
    【解决方案2】:

    从 Blaze (Meteor 0.8.0) 开始,模板永远不会重新渲染。相反,使用细粒度更新。如果您需要知道模板的某个部分何时发生更改,请尝试将该部分放入另一个模板中,并使用该模板的渲染功能。例如,如果您有以下模板:

    <template name="myTemplate">
        {{#if reactiveCondition}}
            <p>The reactive condition is true!</p>
        {{/if}}
    </template>
    

    而您希望在渲染段落时发生一些事情,您需要执行以下操作:

    <template name="myTemplate">
        {{#if reactiveCondition}}
            {{> paragraph}}
        {{/if}}
    </template>
    
    <template name="paragraph">
        <p>The reactive condition is true!</p>
    </template>
    
    Template.paragraph.rendered = function(){
        console.log("The paragraph rendered!")
    }
    

    同样的原理也可以应用于游标。例如以下模板:

    <template name="myTemplate">
        {{#each getCursor}}
            <p>A document in the cursor!</p>
        {{/each}}
    </template>
    

    必须写成:

    <template name="myTemplate">
        {{#each getCursor}}
            {{> document}}
        {{/each}}
    </template>
    
    <template name="document">
        <p>A document in the cursor!</p>
    </template>
    
    Template.document.rendered = function(){
        console.log("A document is rendered!")
    }
    

    【讨论】:

    • 我没有一个不断添加的列表的部分我有一个无尽的滚动。当添加另一个页面时,我希望图像在下载后显示。我真的不知道如何在我的示例中做到这一点,我也不确定什么是 reactiveConditions。另外我不知道你们是否有同样的问题,但现在在我的位置,即使从代理站点也无法访问 docs.meteor.com。
    • @user1898399,同样的原则也适用于游标(见我更新的答案)。而在我的示例中,reactiveCondition 只是一个依赖于响应式数据源(例如 Session)的普通助手。
    • 这让我想到另一个问题。如何从 {{> document}} 模板访问每个光标?谢谢你:)
    • @user1898399,在文档模板中您无法访问光标,但上下文将更改为文档。例如,如果光标中的文档为{a: 1, b: 2},则文档模板中的{{a}} 将评估为1,文档模板中的{{b}} 将评估为2
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多