【问题标题】:Run JS after rendering a meteor template渲染流星模板后运行 JS
【发布时间】:2012-06-16 20:07:56
【问题描述】:

我有一个看起来像这样的模板:

<template name="foo">
  <textarea name="text">{{contents}}</textarea>
</template>

我渲染它:

Template.foo = function() {
  return Foos.find();
}

我有一些事件处理程序:

Template.foo.events = {
  'blur textarea': blurHandler
}

我要做的是根据其内容的大小设置textarearows 属性。我意识到我可以编写一个 Handlebars 助手,但它无法访问正在呈现的 DOM 元素,这将迫使我做一些不必要的重复。理想情况下,我想要的是让流星在渲染元素后触发事件。比如:

Template.foo.events = {
  'render textarea': sizeTextarea
}

这可能吗?

【问题讨论】:

标签: meteor


【解决方案1】:

从 Meteor 0.4.0 开始,可以检查模板是否已完成渲染,请参阅 http://docs.meteor.com/#template_rendered

如果我正确理解您的问题,您应该将您的 textarea 调整大小代码包含在 Template.foo.onRendered 函数中:

Template.foo.onRendered(function () {
  this.attach_textarea();
})

【讨论】:

    【解决方案2】:

    我认为当前的“最佳”方法(有点小技巧)是使用 Meteor.defer ala Callback after the DOM was updated in Meteor.js

    Geoff 是流星的开发者之一,所以他的话就是福音 :)

    所以在你的情况下,你可以这样做:

     <textarea id="{{attach_textarea}}">....</textarea>
    

     Template.foo.attach_textarea = function() {
       if (!this.uuid) this.uuid = Meteor.uuid();
    
       Meteor.defer(function() {
         $('#' + this.uuid).whatever();
       });
    
       return this.uuid;
     }
    

    编辑

    请注意,在 0.4.0 中,您可以以非常特别的方式执行此操作(正如 Sander 所指出的):

    Template.foo.rendered = function() {
      $(this.find('textarea')).whatever();
    }
    

    【讨论】:

    • 为了确保我理解 - 这里有一个动态 id 并没有什么神奇之处,只是每次渲染元素时都会调用这个函数? IE。你可以用数据属性或其他什么来做到这一点?
    • 嗯,Meteor.defer 只是 setTimeout(..., 0) 的包装,对吧?我想到了这种方法,但它可能会导致明显的闪烁。我真的需要一个在事件循环之前的渲染后钩子。
    • 话虽如此,我将接受此答案,因为我的问题与您链接的问题重复(即使该问题的接受答案远非理想)。跨度>
    • @7zark7:动态 id 就在那里,因此您可以在 Defer 调用中找到相关元素。如何执行此操作取决于您,使用 Meteor.uuid 只是一个建议。
    • @TrevorBurnham:是的,(Meteor.setTimeout,见文档)。因此,您希望在附加 DOM 节点之后,但在浏览器呈现节点之前运行一些东西;即在渲染线程返回之前? AFAIK 没有办法解决这个问题,抱歉。
    【解决方案3】:

    大约从 2014 年 6 月开始,正确的做法是使用 Template.myTemplate.onRendered() 设置回调。

    【讨论】:

    • 它不会每次触发,只会触发一次。
    【解决方案4】:

    是的,我想是的——不确定这是否是“正确的方式”,但这对我有用:

    在您的应用程序 JS 中,客户端部分将运行客户端上的任何 javascript。例如:

    if (Meteor.is_client) {
        $(function() {
            $('textarea').attr('rows' , 12) // or whatever you need to do
        })
        ...
    

    注意这里的示例使用 JQuery,在这种情况下,您需要将其提供给客户端(我认为 :-)。就我而言:

    我创建了一个 /client 目录,并在其下添加了 jquery.js 文件。

    希望这会有所帮助。

    【讨论】:

    • 问题在于,虽然这可能适用于初始绘制,但如果元素反应性重绘,它将遇到问题。
    • 另外,Meteor 中不包含 jQuery 吗?我在任何地方都没有 jquery.js 文件,也没有添加任何特殊的 jQuery 包,但我可以在 Meteor 应用程序中使用 jQuery。
    • 我不得不'流星添加 jquery' iirc
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 2017-11-30
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多