将 jQuery 插件附加到 Meteor 模板生成的 DOM 元素 [英] Attaching jQuery plugins to Meteor template-generated DOM elements

查看:54
本文介绍了将 jQuery 插件附加到 Meteor 模板生成的 DOM 元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Meteor 文档,分配给 Template.template_name.rendered 的回调将在 template_name 的每个实例完成渲染后执行.我一直在尝试使用此功能将 jQuery 插件(例如 TagsManager 或 DotDotDot)附加到模板生成的 DOM 元素.做到这一点的自然"方式是这样的:

According to the Meteor documentation, a callback assigned to Template.template_name.rendered will execute after each instance of template_name has finished rendering. I have been trying to use this feature to attach jQuery plugins (such as TagsManager or DotDotDot) to DOM elements generated by the templates. The "natural" way to do this would be something like:

Template.template_name.rendered = function () {
    var template = this;
    var elem = $('input#tags'+template.data._id);
    elem.tagsManager();  // doesn't work
}

然而,这不起作用——预期的行为不会附加到元素上.jQuery 选择器工作正常,通过记录 tagsManager() 的内部结构,我可以看到事件处理程序似乎已附加,但在 .tagsManager() 完成后起来,他们不知何故是独立的.

However, this does not work -- the expected behaviors do not come out attached to the element. The jQuery selector works properly and, by logging the internals of tagsManager(), I can see that the event handlers do seem to get attached, but after .tagsManager() finishes up, they are somehow unattached.

将代码包装在 $(document).ready 或简短的 setTimeout 中的常见"解决方案具有完全相同的行为:

The "usual" solutions of wrapping the code in a $(document).ready or a short setTimeout suffer from the exact same behavior:

Template.template_name.rendered = function () {
    var template = this;
    $(document).ready(function () {
        window.setTimeout(function () {
            var elem = $('input#tags'+template.data._id);
            elem.tagsManager();
        }, 100);  // 0.1 seconds + $(document).ready doesn't work
    });
}

我只是通过给出一个不切实际的高 setTimeout 时间来让它工作,比如 3 秒:

I only got it to work by giving an unrealistically high setTimeout time, such as 3 seconds:

Template.song.rendered = function () {
    var template = this;
    console.log("Template for "+template.data.title+" created");
    $(document).ready(function () {
        window.setTimeout(function () {
            var elem = $('input#tags'+template.data._id);
            elem.tagsManager();
        }, 3000);  // 3 seconds + $(document).ready works
    });
}

事实上,即使将 elem.tagsManager() 替换为简单的 elem.on('click',...) 也会遭受相同的行为如上所述——这就是为什么 Meteor 的人给了我们 Template.template_name.events,我猜.然而,这种破坏了所有有趣的插件,并迫使我们依赖诸如上述的骇人听闻的危险代码.有没有更好的办法?

As a matter of fact, even replacing elem.tagsManager() by a simple elem.on('click',...) suffers from the same behaviors as described above -- which is why the guys at Meteor have given us Template.template_name.events, I guess. However, this kind of breaks all interesting plugins, and forces us to rely on hacky, dangerous code such as the above. Is there a better way?

推荐答案

在模板中,使用 {{#constant}} helper 包裹要应用 jQuery 的 div.这将消除您对包裹元素的所有反应性.

In the template, wrap the div you want to apply the jQuery with {{#constant}} helper. This will kill all reactivity you may have on elements wrapped up.

如果您需要反应性或常量没有帮助,请尝试 这个黑客.我在调用渲染时取消绑定元素的事件,然后立即绑定它.在这种情况下的问题是,渲染被调用了十几次,而且我还没有弄清楚它以某种方式搞砸了.尝试调试它以查看在渲染的第一行中使用 console.log 调用了多少.

If you need reactivity or constant did not help, try this hack. I unbind the event of the element when rendered is called and bind it right after. The problem in this case is that rendered is called like a dozen times and it screw up some way I haven't figured out. Try debugging it to see how many it is called with console.log in the first line of rendered.

希望有帮助!

这篇关于将 jQuery 插件附加到 Meteor 模板生成的 DOM 元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆