2013-01-05 13 views
12

大きなデータセットを一度に大量のデータセットを読み込まなくて済むように、メテオの無限スクロールで読み込んだセクションに分割したい;代わりに、必要に応じてデータセットのチャンクをロードします。 infinite scrollによってロードされた各セクションのライブページの更新を保存しながら、どうすればよいですか?流星で無限のスクロールとリアルタイム更新を行う理想的な方法

答えて

8

ここでは、ムービーデータベースのプレイグラウンドに使用しているコードを示します。私はjQueryのイベントを実験しましたが、データが連続的に転送されるのであれば十分です。私のテストコレクションは680レコードで、20フィールドとサムネイルフィールドが1カバーあたり10-20kbです。ここではCoffeeScriptのコード:

Movies = new Meteor.Collection("movies") 
if Meteor.isClient 
    # starting with 10 items that the user sees a page fast 
    Session.set("queryLimit", 10) 

    # getting the item count from the server collection 
    Meteor.call 'getMoviesCount', (err, result) => 
    Session.set('itemsInQuery',result) 
    # subscribe to a subset of the collection, and change the Session var on completion 
    # automatically changing the limit of the publishing function with autorun 
    Meteor.autorun -> 
    Meteor.subscribe "MoviesList", Session.get("queryLimit"), onComplete = -> 
     if Session.get("queryLimit") < Session.get('itemsInQuery') 
     queryLimit = Session.get("queryLimit") + 30 #change iterator depending on result size 
     Session.set("queryLimit", queryLimit) 

    # Client helper to add more items to handlebars template 
    Template.app.helpers movies: -> 
    Movies.find({}) 

if Meteor.isServer 
    Meteor.publish "MoviesList", (limit) -> 
    # show whole collections once limit is reached, by setting limit to 0 
    limit = 0 if limit > Movies.find().count() 
    console.log new Date(), limit 
    Movies.find({}, { limit: limit, fields: {title:1 } }) #use fields to test different result sizes 

    Meteor.methods 
    getMoviesCount: (query) -> 
     return Movies.find().count() 

とHTML:

<body> 
    {{> app}} 
</body> 
<template name="app"> 
    {{#each movies}} 
     <p>{{title}}</p> 
    {{/each}} 
</template> 

私はいくつかの簡単な性能試験を行なったし、それが判明そのレコードにデータを送信する最も簡単な方法ごとのテキストの数行のためにクライアントには約100の制限があります。ファイルに埋め込まれた10-20kbのサムネイルでも試しました。より大きな資産を使用すると、制限が30レコードを超えたときにChromeが反応しなくなりました。ローカルホスト上で実行 ここではいくつかの統計(3回、それぞれを実行する):

limit seconds till last record rendered. 
    0  79s 
    010 121s 
    020 64s 
    030 45s 
    050 34s 
    100 16s 
    200 16s 

それは流星サーバーが1回(上限= 0)でページ全体を送信するとき、それは周りに79秒を要したことに注意することは興味深いです。大胆な流れが最も速くなければならないので、どうすればこのことが可能かはわかりません。だからおそらく私の統計で面白い何かがあります。何か案は?

1

現在使用しているページを保存するセッションキーを設定できます。例えば、

Session.set("cur_page", 1); 

そして、あなたはあなたのクエリにそのフィード::何かのような

Template.list.items = function() { 
    return Collection.find({}, { 
    skip: Session.get("cur_page") * page_size, 
    limit: page_size 
    }); 
} 

は次に、あなただけのSession.set("cur_page", 2)で値を更新し、あなたのリストは2ページTadaaのためにアイテムを再描画します!

+0

を追加することを考えています索引の使用を失うことなく、後続ページのレコードを飾ることができます。 – Sammaye

+0

私は、ページネーションが間違った単語であることに気付きました。私は、技術的に「ページ」やセクションのデータがページの一番下に表示されるたびに読み込まれるように無限のスクロールを言うことを意図していましたが、あなたがまだページの下部に当たるかどうかにかかわらず、ページの下部または上部に表示されます。これを明確にするために質問を編集します。 – HGandhi

1

私はこれをまだ試していませんでしたが、うまくいくはずです。

var Posts = new Meteor.Collection("posts"); 

そして、あなたのテンプレート:あなたのコレクション持っているのであれば、

<template name="posts"> 
    {{#each posts}} 
     {{> post}} 
    {{/each}} 
</template> 

をこれはあなたのテンプレートヘルパーのようになります。PAGE_SIZEは "あたりの投稿の量がある

Template.posts.helpers({ 
    posts: function() { 
     return Posts.find({}, {limit: Session.get("current_page")*PAGE_SIZE}); 
    } 
}); 

ページ"。ユーザーがページの一番下までスクロールするたびに、「current_page」セッション変数をインクリメントする必要があります。テンプレートが更新され、あなたのinifniteのスクロールがうまくいきます!

3

私のソリューションはAndrej'sに似ています。私は、データベース内のレコードをたくさん持っているので、サーバー上で私が得たので は、私は、私のサーバーは、一度にすべてを送信したくない:

Meteor.publish("items", function(page) { 
    if(!page) 
     page = 1; 
    var limit = 30 * page; 
    return Items.find({}, {limit: limit}; 
} 

クライアント:

Template.templateName.items = function() { 
    Meteor.subscribe("items", Session.get("page")); 
    return Items.find({}); 
} 

とjQueryを

$(window).scroll(function(){ 
    if ($(window).scrollTop() == $(document).height()-$(window).height()){ 
     Session.set("page", Session.get("page") + 1); 
    } 
}); 

をまたテンプレート作成したコールバックのページ最初のページを設定する:

ページの一番下になったかどうかを観察するための機能
Template.templateName.created = function() { 
    Session.setDefault("page", 1); 
}; 

、テンプレートに、私はまた、{{#each}} を使用してこれらの項目を示しています、私がチェックする必要があり、それ以上のレコードが存在しない場合

より良い解決策は、テンプレートが作成されたときに30を表示することであろうと、その後、スクロールでさらに30を得ることができますが、私はそれらを表示する方法がわかりません。私は解決策を持っているかもしれませんが、私はそれがうまくいくかどうか分からないので実装するのは怠惰です。私は、 `)結果セットのサイズ、`スキップ() ​​`常に理想的なソリューションではありませんに応じて、別の解決策は、`(スキップエミュレートする範囲クエリを使用する代わりに、あることに留意すべきでレンダリングされたHTML

関連する問題