cne*_*uro 6 publish-subscribe meteor
我正在获取一组记录并将它们放在一个模板中,让它们渲染{{#each}},我想显示一个加载图标,直到最后一个DOM节点被渲染.
我的问题是我还没有找到一种方法来查询状态/触发最后一个项目的回调,也就是要更新/重新绘制的最后一个DOM节点.
在我的HTML文件中看起来有点像这样:
<template name="stuff">
{{#each items}}
<div class="coolView">{{cool_stuff}}</div>
{{/each}}
</template>
Run Code Online (Sandbox Code Playgroud)
在客户端JS文件中:
// returns all records of Stuff belonging to the currently logged-in user
Template.stuff.items = function () {
Session.set('loading_stuff', true);
return Items.find({owner: Meteor.userId()}, {sort: {created_time: -1}});
};
Template.stuff.rendered = function() {
// every time something new is rendered, there will have been loading of the DOM.
// wait a short while after the last render to clear any loading indication.
Session.set('loading_stuff', true);
Meteor.setTimeout(function() {Session.set('loading_stuff', false);}, 300);
};
Run Code Online (Sandbox Code Playgroud)
loading_stuff在Handlebars帮助器中查询Session变量,如果是,则返回加载类的名称(带有加载器图标GIF)true.
我做尴尬的原因Meteor.setTimeout是因为在每个渲染到模板中的项目之后Template.rendered调用.所以我需要重新确认它仍在加载,但是给它一些时间来加载下一个或者完成全部渲染,稍稍暂停直到它设置为.loading_stufffalse
如何在所有DOM更新结束时(针对特定模板或整个页面)可靠地查询/回调正确的Meteor方式?
非常感谢.
编辑
使用回调的解决方案仅部分工作:subscribe() onReady()
模板在渲染甚至开始之前似乎被称为多次(2-3)次,但是在从服务器返回数据之后,模板依赖于渲染.这意味着它已经"完成"加载数据,但DOM仍在呈现中.我会玩,Meteor.autorun()并看看我是否可以找到一个可靠的钩子来正确地做到这一点.与此同时,我想我的原始问题仍然存在:
我如何知道整个模板/页面何时完成渲染?
最终编辑:
在一天结束时,根据DOM的结构,开发人员可以拥有一个坚如磐石的DOM,并尽可能地将适当的回调附加到他/她想要检查状态的元素上.它可能看起来像一个反气候的脑子,但对我来说,知道模板的最终元素的唯一方法是渲染一个元素,在模板的最末端呈现一个特殊的id,表示结束渲染并附加一个.livequery回调.我希望Meteor将来会更加统一和全球支持检查这个状态.
小智 6
将项目模板嵌套在当前模板中可能实际上有帮助吗?
<template name="stuff">
{{#each items}}
{{> itemTemplate}}
{{/each}}
</template>
<template name="itemTemplate">
<div class="coolView">{{cool_stuff}}</div>
</template>
Run Code Online (Sandbox Code Playgroud)
现在每次将新项更新到DOM时,Template.itemTemplate.rendered上的回调都可以运行.
我发现 JQuery 的 livequery 插件在等待模板中的元素写入 DOM 时不起作用。这是因为该插件侦听 JQuery 方法(如追加),但 Meteor 不使用 JQuery。它使用一个被调用的对象LiveRange来写入 DOM。我修改了我的 livequery JavaScript 文件来处理这个问题。
在文件底部附近,有一行调用registerPlugin(). 我将其修改为如下所示:
$.livequery.registerPlugin([
{object: $.fn, methods: ['append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html']},
{object: LiveRange.prototype, methods: ['insertBefore', 'insertAfter']}
]);
Run Code Online (Sandbox Code Playgroud)
然后我修改了 registerPlugin() 方法,如下所示:
registerPlugin: function(registration) {
for (var i = 0; i < registration.length; i++) {
var object = registration[i].object;
var methods = registration[i].methods;
$.each( methods, function(i,n) {
// Short-circuit if the method doesn't exist
if (!object[n]) return;
// Save a reference to the original method
var old = object[n];
// Create a new method
object[n] = function() {
// Call the original method
var r = old.apply(this, arguments);
// Request a run of the Live Queries
$.livequery.run();
// Return the original methods result
return r;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
这将检查在对象上调用insertBefore()或时元素是否存在,并且仍然像以前一样使用 JQuery。insertAfter()LiveRange
| 归档时间: |
|
| 查看次数: |
5713 次 |
| 最近记录: |