3

カルーセル内に表示したい投稿がたくさんあります。カルーセルには、OwlCarouselを使用します。

    <div class="owl-carousel" id="featured-carousel">
        {{#each featuredPosts}}
        <div>
            <h2>
                {{postTitle}}
            </h2>
        </div>
        {{/each}}
    </div>

私は自分のカルーセルを次のように呼びます:

Template.featuredCarousel.rendered = function(){
$('#featured-carousel').owlCarousel({
    loop:true,
    autoplay:true,
    autoplayTimeout:3000,
    items:1,
    smartSpeed:1080,
    padding:80
});
this.rendered = true;
};

私が得た結果は、フクロウは基本的に、複数の div であるカルーセルに表示するアイテムが 1 つだけあると考えていることです。テンプレートの #each-part が完了する前、またはデータが到着する前に、 Template.featuredCarousel.rendered 内の関数が呼び出されるようです。

テンプレートがすべてのデータを含めて完全にレンダリングされた後にのみ、カルーセルをインスタンス化する関数を呼び出すにはどうすればよいですか?

ご助力ありがとうございます。

PS: 次のようにルーティングに Iron-router を使用します。

Router.map(function(){
this.route('home', {
    path: '/',
    waitOn: function(){
        return Meteor.subscribe('featured');
    },
    data: function(){
        return {featuredPosts: Featured.find({})};
    }
});
});

PPS: ローディング テンプレートも使用してみましたが、どちらも役に立ちません。

4

2 に答える 2

6

次のように述べて、問題を正しく特定しました。

テンプレートの #each-part が完了する前、またはデータが到着する前に、 Template.featuredCarousel.rendered 内の関数が呼び出されるようです。

テンプレートのrenderedコールバックは、テンプレート インスタンスが最初に DOM に挿入されたときに 1 回だけ呼び出されるため、データの準備ができていない (サーバーから取得された) 場合でも、#each ブロックは HTML 要素を生成せず、カルーセルをインスタンス化するときに呼び出されます。空に見えます。

できることは、renderedコールバックが発生する前にデータの準備ができていることを確認することです。どうやらこのソリューションをうまくセットアップしようとしたようですが、デフォルトの読み込みフックをそのように追加しましたか?

Router.onBeforeAction("loading");

さらに良い解決策は、レンダリングされたコールバックでデータベースの変更をリッスンし、アイテムが最初にフェッチされたときにそれに応じてカルーセルを再初期化し、動的に追加および/または削除することです。

HTML

<template name="carousel">
  <div class="owl-carousel">
    {{#each featuredPosts}}
      {{! item declaration}}
    {{/each}}
  </div>
</template>

JS

function featuredPosts(){
  return Featured.find();
}

Template.carousel.helpers({
  // feed the #each with our cursor
  featuredPosts:featuredPosts
});

Template.carousel.rendered=function(){
  var options={...};
  // first initialization
  this.$(".owl-carousel").owlCarousel(options);
  this.autorun(_.bind(function(){
    // this is how we "listen" for databases change : we setup a reactive computation
    // and inside we reference a cursor (query) from the database and register
    // dependencies on it by calling cursor.forEach, so whenever the documents found
    // by the cursor are modified on the server, the computation is rerun with
    // updated content, note that we use the SAME CURSOR that we fed our #each with
    var posts=featuredPosts();
    // forEach registers dependencies on the cursor content exactly like #each does
    posts.forEach(function(post){...});
    // finally we need to reinit the carousel so it take into account our newly added
    // HTML elements as carousel items, but we can only do that AFTER the #each block
    // has finished inserting in the DOM, this is why we have to use Deps.afterFlush
    // the #each block itself setup another computation and Deps.afterFlush makes sure
    // this computation is done before executing our callback
    Tracker.afterFlush(_.bind(function(){
      this.$(".owl-carousel").data("owlCarousel").reinit(options);
    },this));
  },this));
};

私は owl-carousel に詳しくないので、reinit が適切に動作するかどうかはわかりません (ドキュメントをすぐに確認したところ、問題ないようです)。

再初期化メソッドが利用できない同様の JS プラグイン (ブートストラップ カルーセルなど) の場合、最初にプラグインがインスタンス化されているかどうかを確認してから破棄し、次のように再作成できます。

var carousel=this.$(".carousel").data("bs.carousel");
if(carousel){
  // bootstrap carousel has no destroy either so we simulate it by pausing it
  // and resetting the data attribute to null (it's a bit messy)
  this.$(".carousel").carousel("pause");
  this.$(".carousel").data("bs.carousel",null);
}
// initialize normally because previous instance was killed
this.$(".carousel").carousel({...});
于 2014-08-17T22:54:27.167 に答える
0

#each が onRender 以外で終了した直後に、テンプレートからヘルパー ハンドラを呼び出すほうがよいでしょう。

ループが終了し、DOM がロードされるとすぐに、ハンドラーは関数を呼び出します。

あなたの場合のように、各ハンドラーを として配置した後{{initializeCarousel}}

{{#each featuredPosts}} {{! item declaration}} {{/each}} {{initializeCarousel}}

これをヘルパーで次のように定義します。

Template.carousel.helpers({ // feed the #each with our cursor
    initializeCarousel: function(){
        $('#featured-carousel').owlCarousel({
            loop:true, autoplay:true, autoplayTimeout:3000, items:1, smartSpeed:1080, padding:80 
        });
    });

これにより、データが読み込まれるとカルーセルが読み込まれます。これが役立つことを願っています。

于 2016-01-27T12:42:51.143 に答える