繁体   English   中英

MeteorJS:依次加载…模板

[英]MeteorJS: Loading… templates sequentially

因此,基本上,我有一个包含多种类别照片的收藏集。 我目前使用此设置来浏览类别并为每个类别加载模板:

{{#each categories}}
  {{>gallery collectionName=categoryName}}
{{/each}}

因此,这对于使用Gallery模板动态构建每个部分非常有用。

由于每个画廊都有自己的图像集合,因此我在画廊模板内添加了一个辅助函数来调用相应的集合,然后针对每个集合图像将其添加到画廊中。

(在图库模板内)

{{loadPhotos collectionName}}

现在,您可能可以看到问题了。

首先创建图库div,将其创建为空,然后一次全部创建,然后将所有照片添加到所有div中。

我希望每个画廊都显示一个加载圈,直到所有照片都添加完毕,然后下一个画廊开始加载照片,并且加载所有照片时,加载圈消失。 这将继续,直到所有类别都已加载。

我正在使用jQuery添加照片和FlowRouter,如果有帮助...

感谢您的时间和提供的任何解决方案!

过去,我不得不做类似的事情,而我能够做的是通过创建一种在模板和子模板之间进行通信的方式。 完成此操作的主要方法是将回调函数传递给每个子模板,或者传递ReactiveVarReactiveDict或父级“监听”的任何其他反应式计算。 我测试了以下方法,它应该完全适合您的需求。

首先是主要类别模板。

<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM