Meteor:oncreated与onrendered的区别

6

问题:

  • oncreated:模板尚未呈现(每个模板仅触发一次)。
  • onrendered:模板已呈现(可多次触发)。

是否可能仅在模板完全呈现后触发函数?

我有一系列类似于此的消息列表:

<template name="messages">
    <div id="messages">
        <span class="message">{{this.message}}</span>
    </div>
</template>

每当将新消息插入DOM时,我想知道消息的文本是否包含用户名。

下面的代码片段会多次运行,但它应该只运行一次。

Template.messages.rendered = function() {

    var username = Meteor.user().services.twitter.screenName;
    $("#messages").bind("DOMSubtreeModified", function() {    
        var lastmessage = $('.message').last().text();
        if (lastmessage.indexOf(username) > -1) {
            //Do something
        }
    }
}

通过创建并更改模板以包含单个消息,可以交替呈现已创建的内容,并使函数每次针对新消息运行一次。这意味着它获取最后一个消息变量的倒数第二个值:

Template.message.created = function() {
    var username = Meteor.user().services.twitter.screenName;

    var lastmessage = $('.message').last().text();//this is not the last message
    if (lastmessage.indexOf(username) > -1) {
        //Do something
    }
}

1
文档中指出,onRendered 只会触发一次:“使用此方法添加的回调函数仅在 Template.myTemplate 的实例被渲染为 DOM 节点并首次放入文档中时调用一次。” - foobarbecue
在我的情况下,新消息一直添加到模板中,并且每个消息都会重新呈现。设置超时似乎是唯一有效的方法,尽管这可能不是Meteor最佳实践。 - Fullhdpixel
@Fullhdpixel,这不是JavaScript或任何其他编程语言的良好实践。这样会破坏你的代码,如果你像这样破坏你的代码,将越来越难以维护这样的代码。你应该找出为什么你的onRendered被多次触发的原因。 - Lukas1
1
我不确定你为什么要在onRendered/onCreated中这样做,但看起来这个功能的正确位置应该是helper中,但你必须考虑到helpers会被多次调用。 - Lukas1
2个回答

1
说实话,你可以在“渲染”中做类似的事情。或者在将额外的内容呈现到DOM后,您可以加入一些回调函数。
此外,您可以使用self.autorun(() => { if(self.alreadyRun) return; ... })self.alreadyRun = new ReactiveVar(false)
只是猜测!
var self = this;

self.alreadyRun = false;
if(self.alreadyRun){
    self.alreadyRun = true;

    // run once code here

}

-2

通过将代码包装在setTimeout函数中解决了这个问题。


1
Meteor.defer也用于同样的目的。 - Nathan Lippi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接