【问题标题】:jQuery in Template.rendered gets called but doesn't take effectTemplate.rendered 中的 jQuery 被调用但不生效
【发布时间】:2026-02-01 13:45:02
【问题描述】:

我遇到了以下无法调试的问题:

我有一个我要去的 textarea 字段列表

<template name="sampleTemplate">
<ul>
  {{#each listOfTextFields}}
   < li > < textarea id="{{_id}}" > </li>
  {{/each}}
</ul>
</template>

为了呈现该列表,我有

Template.sampleTemplate.listOfTextFields = function () {
   return applicationDB.find({ //some fields })
}

我还有一个映射到 textareas 的事件,当我按下“enter”键时,我将一个新文档插入到集合中。发生这种情况时,会重新渲染模板并显示新的文本区域。

Template.sampleTemplate.events({
   'keydown enter' : function (enterEv) {
        //add new document to collection
        Session.set("newTextAreaCreated", 1);
        Session.set("newItemId", newItemId);

    }
}

然后...为了使它对用户更友好,我尝试将 focus() 放在那个新创建的文档上。所以我在我的渲染函数中有:

Template.sampleTemplate.rendered = function () {
    if (Session.get("newTextAreaCreated") == 1){
        console.log("new text area is created")
        $(document.getElementById(Session.get("newItemId")).focus();
    }
Session.set("newTextAreaCreated", 0);
}

上面的代码在我当前位于最后一个 textarea 字段时有效,当我按下回车键时,它成功创建了新项目,并专注于它。 我有一大堆处理排序的其他代码,所以新项目肯定是在新项目下创建的(以防你们中的一些人可能想知道)。

但是 - 当我在中间的某个地方返回列表时,我按 Enter 键,它成功地创建了它下面的项目,但是它并没有关注它。我使用了 console.logs 来确保渲染的函数被调用并且确实被调用了,但是焦点并不明显。

这可能与跳行的文本区域上的“输入”效果有关吗?或者可能是完全不同的东西。如果 textareas 引起问题等,我很乐意实施更好的解决方案。

【问题讨论】:

  • 在 Template.sampleTemplate.rendered 函数中尝试添加 console.log('rendered', Session.get("newTextAreaCreated")) 并查看它是否被命中以及输出什么。我不会依赖被多次调用的渲染函数,这在新版本的 UI 中改变为只被调用一次。你总是可以在if 周围包裹一个Deps.autorun,所以如果newTextAreaCreated 发生变化,它将再次被调用。
  • 尝试实现相同的功能,但不要使用enter 键。为什么不使用更标准(和直观)的东西,比如add button
  • 另外,你的事件回调中那个神秘的newItemId 变量是什么?
  • 我已经设法找到了这个错误......代码实际上是可以工作的,只是由于mongodb查询中的一个小错误,它导致焦点集中在错误的元素上。

标签: jquery meteor


【解决方案1】:

在列表项周围放置一个 {{#isolate}} 块,并将文档插入委托给服务器端的流星方法。隔离助手将确保父模板不会重新渲染,服务器端流星方法将保证模拟不会在集合插入上运行。这样,render() 只会被触发一次,你可以做 DOM 相关的事情,比如聚焦或动画。

【讨论】:

  • 我部分实现了你提到的一些事情。我将一条更新语句移动到服务器端并对其进行了修改,以便它进行多行更新(这意味着它只运行一次)并因此而让 render() 只运行一次。
最近更新 更多