2014-09-10 9 views
6

गाया जाता है मैं निम्नलिखित टेम्पलेट कोडउल्का: जब तक प्रतीक्षा करें सभी टेम्पलेट्स

<template name="home"> 
    <div class="mainBox"> 
     <ul class="itemList"> 
      {{#each this}} 
       {{> listItem}} 
      {{/each}} 
     </ul> 
    </div> 
</template> 

<template name="listItem"> 
    <li class="item"> 
     {{username}} 
    </li> 
</template> 

है और मैं एक कोड एक बार सभी "ListItem" का गाया जाता है पर अमल करना चाहते हैं। उनमें से लगभग 100 हैं। मैंने निम्नलिखित

Template.home.rendered = function() { 
    // is this called once all of its 'subviews' are rendered? 
}; 

पर प्रयास किया लेकिन यह तब तक इंतजार नहीं करता जब तक कि सभी विचार लोड नहीं हो जाते।

सभी उप-दृश्य टेम्पलेट लोड होने पर जानने का सबसे अच्छा तरीका क्या है?

+0

क्या आप कहीं डेटा की सदस्यता लेते हैं? क्या आप लौह राउटर का उपयोग कर रहे हैं? –

+0

'सूची इटैम' टेम्पलेट्स संभावित रूप से प्रतिक्रियाशील संग्रह से डेटा प्राप्त करते हैं, इस मामले में आप कभी भी यह सुनिश्चित नहीं कर सकते कि उनमें से सभी * प्रस्तुत किए गए हैं। प्रारंभिक सेट तैयार होने पर आप अधिसूचना प्राप्त करने के लिए कुछ युक्तियों का उपयोग कर सकते हैं। फिर भी, आप शायद "उल्का रास्ता" में कुछ नहीं करने की कोशिश कर रहे हैं, इसलिए मैं एक बेहतर समाधान की तलाश में हूं। आप क्या हासिल करने का प्रयास कर रहे हैं? –

उत्तर

3

यह मैं कैसे आगे बढ़ना है:

client/views/home/home.html

<template name="home"> 
    {{#if itemsReady}} 
    {{> itemsList}} 
    {{/if}} 
</template> 

<template name="itemsList"> 
    <ul> 
    {{#each items}} 
     {{> item}} 
    {{/each}} 
    </ul> 
</template> 

<template name="item"> 
    <li>{{value}}</li> 
</template> 

client/views/home/home.js

Template.home.helpers({ 
    itemsReady:function(){ 
    return Meteor.subscribe("items").ready(); 
    } 
}); 

Template.itemsList.helpers({ 
    items:function(){ 
    return Items.find(); 
    } 
}); 

Template.itemsList.rendered=function(){ 
    // will output 100, once 
    console.log(this.$("li").length); 
}; 

lib/collections/items.js

Items=new Mongo.Collection("items"); 

server/collections/items.js

insertItems=function(){ 
    var range=_.range(100); 
    _.each(range,function(index){ 
    Items.insert({value:"Item "+index}); 
    }); 
}; 

Meteor.publish("items",function(){ 
    return Items.find(); 
}); 

server/startup.js

Meteor.startup(function(){ 
    Items.remove({}); 
    if(Items.find().count()===0){ 
    insertItems(); 
    } 
}); 

हम निर्दिष्ट है कि हम, आइटम की हमारी सूची को रखना चाहते हैं केवल जब प्रकाशन के लिए तैयार है तो द्वारा उस समय डेटा उपलब्ध है और li तत्वों की सही संख्या मिल जाएगा सूची में प्रदर्शित कॉलबैक में प्रदर्शित।

अब एक ही का उपयोग कर

iron:routerwaitOn सुविधा:

client/views/home/controller.js

HomeController=RouteController.extend({ 
    template:"home", 
    waitOn:function(){ 
    return Meteor.subscribe("items"); 
    } 
}); 

client/lib/router.js

Router.configure({ 
    loadingTemplate:"loading" 
}); 

Router.onBeforeAction("loading"); 

Router.map(function(){ 
    this.route("home",{ 
    path:"/", 
    controller:"HomeController" 
    }); 
}); 

client/views/loading/loading.html

<template name="loading"> 
    <p>LOADING...</p> 
</template> 

iron:router का उपयोग करना संभवतः बेहतर है क्योंकि यह एक सामान्य पैटर्न को सुन्दर तरीके से हल करता है: हमें आइटम की आवश्यकता नहीं है, अब और अधिक पढ़ें, होम टेम्पलेट केवल तभी प्रदान किया जाएगा जब WaitList प्रतीक्षा करके लौटाया जाएगा, वैश्विक रूप से तैयार हो जाएगा।

किसी को एक लोडिंग टेम्पलेट जोड़ने और डिफ़ॉल्ट "लोडिंग" हुक सेट अप करना न भूलना अन्यथा यह काम नहीं करेगा।

+0

बस मेरे सैमसंग के जवाब में जोड़ना - मेरे मार्ग में, मेरे पास "डेटा:" फ़ंक्शन था, लेकिन "सदस्यता" समाप्त होने से पहले डेटा फ़ंक्शन स्वयं चलता है, इसलिए, आपको "this.ready()" सशर्त-चेक बनाने की आवश्यकता है सुनिश्चित करें कि सभी डेटा लौटाया गया है - https://github.com/EventedMind/iron-router/issues/265 – ericbae

0

इस तरह

की विधि गाया काम करता है इसके लिए कॉलबैक एक बार जब Template.myTemplate का एक उदाहरण डोम नोड्स में गाया और पहली बार के लिए दस्तावेज़ में डाल दिया है कहा जाता है।

इसलिए, जब प्रस्तुत किया जाता है तो आपके पास इस मामले में परिवर्तनीय प्रतिक्रियाशील नहीं है।

// this would sufficient 
Template.listItem.helpers = function() { 
    username:function(){ 
     return ... 
    } 
}; 
0

मैं की तरह कुछ सुझाव देंगे:

var unrendered = []; 

Template.listItem.created = function() { 
    var newId = Random.id(); 
    this._id = newId; 
    unrendered.push(newId); 
}; 

Template.listItem.rendered = function() { 
    unrendered = _.without(unrendered, this._id); 
    if (!unrendered.length) { 
    // WHATEVER NEEDS DOING WHEN THEY'VE ALL RENDERED 
    } 
}; 

चेतावनी

यह धारणा इससे पहले कि वे सबसे पहले प्रस्तुत किए गए हों अनिवार्य रूप से सभी टेम्पलेट उदाहरणों बनाया जाएगा कि पर काम करता है अन्यथा, आपका कोड इसे चलाने से पहले चलाएगा। I सोचें यह मामला होना चाहिए, लेकिन आपको इसे आजमाने की आवश्यकता होगी क्योंकि मेरे पास वास्तव में 100+ उप-टेम्पलेट परीक्षण चलाने का समय नहीं है। यदि यह मामला नहीं है, तो मैं यह नहीं देख सकता कि आप इस व्यवहार को कैसे पहले प्राप्त कर सकते हैं, वास्तव में कितने उप-टेम्पलेट बनाए जाएंगे।

आप पता है कि कितने वहाँ तो उपरोक्त कोड एक काउंटर है कि हर बार rendered रन decrements को सरल किया जा सकता हो जाएगा करना हैं, और यह आसान है।

unrendered = [number of listitems]; 

Template.listItem.rendered = function() { 
    unrendered--; 
    if (!unrendered) { 
    // WHATEVER NEEDS DOING WHEN THEY'VE ALL RENDERED 
    } 
}; 

इसके अलावा, आप meteor add random करना पड़ सकता है, लेकिन मैं इस पैकेज अब कोर में शामिल है लगता है।

1

मुझे एक ही समस्या है जिसमें एक स्लिम जावास्क्रिप्ट कैरोसेल प्लगइन (या चार्ट या ग्राफ जैसे किसी भी अच्छे जावास्क्रिप्ट प्लगइन को कॉल करने से पहले लोड करने के लिए लोड करने के लिए मेरे सभी सबटेम्प्लेट्स पर इंतजार करने की आवश्यकता है) जिसे कॉल करने से पहले डीओएम में लोड किए गए आपके पूरे डेटा सेट की आवश्यकता होती है) ।

मैंने इसे सबटेम्प्लेट के रैंक की तुलना केवल समग्र गिनती से तुलना करके हल किया जिसे मैं जो भी क्वेरी कर रहा था, उसके लिए वापस किया जाना चाहिए। एक बार रैंक गिनती के बराबर हो जाने पर, आप अपनी प्लगइन को subtemplate.rendered सहायक से कॉल कर सकते हैं क्योंकि सभी उप-टेम्पलेट्स को DOM में डाला गया है। तो अपने उदाहरण में:

Template.home.helpers({ 

    listItems: function() {   
     return ListItems.find({/* whatever query */}).map(function(listItem, index) { 
      listItem.rank = index + 1; // Starts at 1 versus 0, just a preference 
     }); 
    } 
} 
0

जाहिर है वहाँ अपनी स्थिति को संभालने के लिए विभिन्न तरीके हैं:

Template.listItem.rendered = function() { 

    if(this.data.rank === ListItems.find({/* whatever query */}).count()) { 
     console.log("Last item has been inserted into DOM!"); 
     // Call your plugin 
     $("#carousel").owlCarousel({ 
      // plugin options, etc. 
     }); 
    } 
} 

तो फिर तुम सिर्फ अपने सहायक listItems के लिए एक रैंक, जो काफी आसान है लौटना ही होगा। आप आसानी से टेम्पलेट सदस्यता का उपयोग कर सकते हैं।

Template.myView.onCreated(function() { 
    var self = this; 

    self.autorun(function(){ 
     self.mySub = self.subscribe('mySubscription'); 
    }); 

    if(self.mySub.ready()) { 
     // my sweet fancy code... 
    } 
}); 


<template name="myTemplate"> 
    <ul> 
     {{#if Template.subscriptionsReady}} 
      {{#each items}} 
       <li>{{item}}</li> 
      {{/each}} 
     {{else}} 
      <div class="loading">Loading...</div> 
     {{/if}} 
    </ul> 
</template> 
संबंधित मुद्दे