[英]MeteorJS: Loading… templates sequentially
因此,基本上,我有一个包含多种类别照片的收藏集。 我目前使用此设置来浏览类别并为每个类别加载模板:
{{#each categories}}
{{>gallery collectionName=categoryName}}
{{/each}}
因此,这对于使用Gallery模板动态构建每个部分非常有用。
由于每个画廊都有自己的图像集合,因此我在画廊模板内添加了一个辅助函数来调用相应的集合,然后针对每个集合图像将其添加到画廊中。
(在图库模板内)
{{loadPhotos collectionName}}
现在,您可能可以看到问题了。
首先创建图库div,将其创建为空,然后一次全部创建,然后将所有照片添加到所有div中。
我希望每个画廊都显示一个加载圈,直到所有照片都添加完毕,然后下一个画廊开始加载照片,并且加载所有照片时,加载圈消失。 这将继续,直到所有类别都已加载。
我正在使用jQuery添加照片和FlowRouter,如果有帮助...
感谢您的时间和提供的任何解决方案!
过去,我不得不做类似的事情,而我能够做的是通过创建一种在模板和子模板之间进行通信的方式。 完成此操作的主要方法是将回调函数传递给每个子模板,或者传递ReactiveVar
, ReactiveDict
或父级“监听”的任何其他反应式计算。 我测试了以下方法,它应该完全适合您的需求。
首先是主要类别模板。
<template name="photoGallery">
{{#each cat in categories}}
{{> gallery collectionName=cat.name loadNow=loadTrigger isLoaded=loadedIndicator}}
{{/each}}
</template>
以及相关的Javascript。 请注意,在此示例中,我正在订阅一个名为photoCategories
的出版物,该出版物从名为Categories
的集合中发布了一组文档(该集合在name
属性中包含画廊类别的列表,并希望它们在loadOrder
属性中加载的loadOrder
)。 您的具体情况可能有所不同。
import { Template } from 'meteor/templating';
import { Categories } from '../../../api/categories/categories.js';
import { ReactiveDict } from 'meteor/reactive-dict';
import { ReactiveVar } from 'meteor/reactive-var';
import './photoGallery.html';
import '../utils/loading-indicator.html';
Template.photoGallery.onCreated(function() {
this.loadTrigger = new ReactiveDict('loadTrigger');
this.lastLoaded = new ReactiveVar();
this.loadOrder = [];
// subscribe to category data and when complete build loading controls
// in this example the collection that contains the categories is called
// 'Categories' and each document contains a property called 'loadOrder'
// to control the order to load the galleries
this.subscribe('photoCategories', () => {
// we are inside the 'onComplete' subscription callback
Categories.find({}, {sort: {loadOrder: 1}}).forEach((category) => {
// create a trigger for each gallery so we can communicate when to load
// initialize each trigger to false for now
this.loadTrigger.set(category.name, false);
// we need to also keep track of our load order so we know which
// gallery to trigger next
this.loadOrder.push(category.name);
});
// now that everything is initialized, lets trigger the first gallery to load
this.loadTrigger.set(this.loadOrder[0], true);
});
// re-runs everytime a gallery is finished loading
this.autorun(() => {
// get which gallery just finished loading
var lastLoaded = this.lastLoaded.get();
var lastLoadedIndex = this.loadOrder.indexOf(lastLoaded);
// make sure we have more galleries to load
if (lastLoadedIndex + 1 < this.loadOrder.length) {
// get the next gallery to load
var loadNext = this.loadOrder[lastLoadedIndex + 1];
// trigger the gallery to load
Tracker.afterFlush(() => {
this.loadTrigger.set(loadNext, true);
});
}
});
});
Template.photoGallery.helpers({
// returns our photo gallery categories to iterate over in our template
categories: function() {
return Categories.find({}, {sort: {loadOrder: 1}});
},
// returns our ReactiveDict so we can communicate to our sub-template
// galleries when they can load
loadTrigger: function() {
return Template.instance().loadTrigger;
},
// returns our ReactiveVar used to keep track of which gallery just loaded
loadedIndicator: function() {
return Template.instance().lastLoaded;
},
});
基本上,我们在这里所做的是订阅包含类别列表的出版物。 然后,我们建立一个加载触发器字典,用它来触发每个画廊的加载。 我们还需要定义一个最后加载的触发器,以便我们知道画廊何时加载(并可以触发下一个加载)。
为了确保所有操作均正常进行,我们需要确保将加载触发器和最后加载的触发器传递给图库模板(以便可以触发它们加载并在完成后指示返回)。
现在,让我们看一下图库模板。
<template name="gallery">
{{#if okToLoadNow collectionName}}
{{loadPhotos collectionName}}
{{else}}
{{> loading_indicator }}
{{/if}}
</template>
以及相关的javascript。
Template.gallery.helpers({
// reactive checks if we are ok to load
okToLoadNow: function(collectionName) {
return Template.instance().data.loadNow.get(collectionName);
},
// contains logic that loads photos, renders them on the page, then triggers
// back once the loading is complete
loadPhotos: function(collectionName) {
const instance = Template.instance();
// insert the code that loads the photos and renders them on the page here!
// if the logic is complete it probably makes more sense to put this in a sub-template
// and put the logic in the `onRendered` callback
// lets simulate loading by pausing for 3 seconds then communicate back
// that we loaded
Meteor.setTimeout(() => {
instance.data.isLoaded.set(collectionName);
}, 3000);
},
});
在图库模板中,我们将显示一个加载指示器,直到触发加载。 加载完成后,然后(通过isLoaded触发器)指示已完成。 为此,我们只需传回刚刚加载的图库名称。
如前所述,我能够测试这种方法是否有效。 您应该只能够根据自己的具体情况进行调整。
让我知道事情的后续!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.