2013-01-05 7 views
12

में अनंत स्क्रॉल और वास्तविक समय अपडेट करने का आदर्श तरीका मेरे पास डेटा का एक बड़ा सेट है जिसे मैं एक बड़े डेटासेट को लोड करने से रोकने के लिए उल्का में अनंत स्क्रॉल के माध्यम से लोड किए गए अनुभागों में विभाजित करना चाहता हूं ; इसके बजाय जब आवश्यक हो तो मैं डेटासेट के हिस्सों को लोड करूंगा। infinite scroll द्वारा लोड किए गए प्रत्येक अनुभाग पर लाइव पेज अपडेट को संरक्षित करते समय मैं ऐसा कैसे करूं?मीटियर

उत्तर

8

यहां कोड है जिसे मैं मूवी डेटाबेस प्लेग्राउंड के लिए उपयोग कर रहा हूं। मैंने jQuery घटनाओं के साथ प्रयोग किया, लेकिन आखिर में फैसला किया कि डेटा पर्याप्त रूप से स्थानांतरित होने पर पर्याप्त है। मेरा परीक्षण संग्रह 680 रिकॉर्ड है, जिसमें 20 फ़ील्ड और एक थंबनेल फ़ील्ड है जो 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() 

और एचटीएमएल:

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

मैं कुछ त्वरित प्रदर्शन परीक्षण किया था और यह पता चला है कि रिकॉर्ड उनका जल्द से जल्द करने के लिए डेटा भेजने के लिए प्रति पाठ की कुछ लाइनों के लिए ग्राहक 100 के आसपास एक सीमा है। मैंने इसे 10-20 केबी थंबनेल के साथ भी कोशिश की जो फ़ाइल में एम्बेडेड हैं। बड़ी संपत्तियों का उपयोग करते समय क्रोम काफी अप्रतिबंधित हो गया जब सीमा 30 से अधिक रिकॉर्ड थी। यहाँ कुछ स्थानीय होस्ट पर किया आँकड़े (चलाने 3x प्रत्येक):

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

यह ध्यान रखें कि यह चारों ओर 79 रों ले लिया जब उल्का सर्वर एक ही बार (सीमा = 0) में पूरे पृष्ठ भेजता है दिलचस्प है। मुझे यकीन नहीं है, यह कैसे संभव हो सकता है, क्योंकि एक सतत स्ट्रीम सबसे तेज़ होना चाहिए। तो शायद मेरे आंकड़ों के साथ कुछ मजाकिया है। कोई विचार?

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

संलग्न करने के बारे में सोच रहा हूं, यह ध्यान दिया जाना चाहिए कि, परिणाम सेट आकार के आधार पर, 'छोड़ें)' हमेशा आदर्श समाधान नहीं होता है, दूसरा समाधान 'skip() 'अनुकरण करने के लिए रेंज क्वेरी का उपयोग करने के बजाय होता है। आगे के पृष्ठों के लिए रिकॉर्ड गार्निश करने के लिए इंडेक्स उपयोग के नुकसान के बिना। – Sammaye

+0

मुझे अभी एहसास हुआ कि अंकन गलत शब्द है। मैं अब तक अनंत स्क्रॉल कहूंगा क्योंकि तकनीकी रूप से "पृष्ठ" या डेटा के लायक डेटा हैं जो हर बार पृष्ठ के निचले भाग पर लोड होते हैं, लेकिन आपको अभी भी अपडेट करने की आवश्यकता है या नहीं, पृष्ठ के नीचे या शीर्ष पर। मैं इसे स्पष्ट करने के लिए प्रश्न संपादित करूंगा। – HGandhi

1

मैंने अभी तक यह कोशिश नहीं की है, लेकिन इसे काम करना चाहिए। तो, अगर आप अपने संग्रह है:

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

और अपने टेम्पलेट:

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

यह आपके टेम्पलेट सहायक हो सकता है:

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

जहां PAGE_SIZE प्रति "पोस्ट की मात्रा है पृष्ठ"। जब भी उपयोगकर्ता पृष्ठ के निचले भाग तक स्क्रॉल करता है, तो आपको "current_page" सत्र चर को बढ़ाने की आवश्यकता होती है। फिर टेम्पलेट अपडेट हो जाएगा और आपकी इन्फिनिट स्क्रॉल (उम्मीद है) काम करता है!

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 और प्राप्त करने के लिए, लेकिन मुझे नहीं पता कि उन्हें कैसे दिखाना है। मेरे पास समाधान हो सकता है, लेकिन मैं लागू करने के लिए आलसी हूं क्योंकि मुझे यकीन नहीं है कि यह काम चल रहा है या नहीं। मैं प्रस्तुत एचटीएमएल

संबंधित मुद्दे