我有这个Meteor项目:https://github.com/jfahrenkrug/code_buddy
它基本上是一个带有大文本区域和预先区域的工具,可让您输入自动推送到所有连接客户端的源代码片段。
我想在代码更改时自动运行highlightSyntax函数,但它确实没有用。
我已尝试过query.observe,但这并没有太好用:语法高亮显示一次,然后再次消失。
所以我的问题是:如何在更新DOM后运行代码?
答案 0 :(得分:33)
一种愚蠢的方法是:
<强> foo.html 强>
<template name="mytemplate">
<div id="my-magic-div">
.. stuff goes here ..
{{add_my_special_behavior}}
</div>
</template>
<强> foo.js 强>
Template.mytemplate.add_my_special_behavior = function () {
Meteor.defer(function () {
// find #my-magic-div in the DOM
// do stuff to it
});
// return nothing
};
每当渲染(或重新渲染)模板时都会调用该函数,因此您可以将其用作钩子来执行您想要执行的任何特殊DOM操作。你需要使用Meteor.defer(它与settimeout(f,0)的作用相同),因为在渲染模板时,它还没有在DOM中。
请记住,您可以在不将其插入DOM的情况下渲染模板!例如,这样做是完全合法的:
console.log(Template.mytemplate())
因此,当呈现模板时,不能100%保证它最终会在DOM中结束。这取决于模板的用户。
答案 1 :(得分:29)
从Meteor 0.4.0开始,Template.myTemplate.rendered
提供了回调
将Template.myTemplate的实例渲染到DOM节点并首次放入文档时,的更多信息称为一次
。
答案 2 :(得分:9)
对于当前版本的Meteor(1.0),我们现在可以使用Tracker的.afterFlush()功能。
Tracker.autorun(function(e){
var data = Router.current().data();
if(data.key !== undefined){
//the data is there but dom may not be created yet
Tracker.afterFlush(function(){
//dom is now created.
});
}
});
答案 3 :(得分:3)
更新DOM后没有回调,但您可以使用Tracker.flush()
强制所有待处理的DOM更新。
致电flush()
后,您知道DOM已更新,因此您可以执行所需的任何手动DOM更改。
答案 4 :(得分:2)
这个问题相当陈旧,但两年后的解决方案是集成operational transformation library with Meteor并在客户端上使用Ace或CodeMirror,它会自动突出显示语法。这具有允许人们同时编辑的额外好处。
我已经为你完成了工作:)
答案 5 :(得分:1)
在Blaze Components(我是作者之一)中,您有一个API,可以在插入,移动或删除DOM时调用方法。您可以see here在DOM更改时如何制作反应变量。
这种方法的缺点是,当DOM元素属性发生变化时(例如incNumKids()
更改),它不会发生变化。仅当DOM元素本身被更改时。这适用于大多数情况,但如果您需要第二种情况,我建议您只使用MutationObserver。在这种情况下,您还可以对外部变化做出回应。
答案 6 :(得分:0)
似乎Template.myTemplate.rendered
无法正常工作或我无法获得......
我需要在渲染了所有帖子的模板后加载TinyMCE内联,所以我有:
<div id="wrapper">
{{#each posts}}
<div class="editable">{{post}}</div>
{{/each}}
</div>
Template.myPosts.rendered = function(){
console.dir($("div"));
tinymce.init({
selector: "div.editable",
inline: true,
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table contextmenu paste"
],
toolbar: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
});
}
但是,控制台仅记录<div id="wrapper">
而不是<div class="editable">
div,其中包含我的帖子。因此,在呈现模板之前似乎发生了Template.myTemplate.rendered
回调,对吗?
编辑:我将Template.myTemplate.rendered
代码放在setTimeout()
内,似乎一切正常,所以我确定Template.myTemplate.rendered
会导致问题。
答案 7 :(得分:0)
我刚刚发现了一个似乎工作得很好的小黑客:
Template.myTemplate.onRendered(function() {
this.autorun(function() {
Meteor.setTimeout(function() {
// DOM has been updated
}, 1);
});
});
我不是流星专家所以它可能有一些缺点,但我现在还没有找到 - 除了它有点脏!
答案 8 :(得分:-2)