[英]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.