2013-05-01 12 views
6

Perché nel seguente esempio di base la raccolta restituita all'interno della funzione di rendering è vuota?
Autopublish è abilitato. Dopo il caricamento della pagina di comando
Coll.find().fetch() chiamata all'interno javascript console ritorna insieme corretto di vociMeteor template.rendered - Perché la raccolta è vuota?

Ecco il codice

t.js

Coll = new Meteor.Collection("coll"); 

if (Meteor.isClient) { 
    Template.tpl.rendered = function(){ 
    console.log(Coll.find().fetch()); // <-- This line prints empty array 
    }; 
} 

if (Meteor.isServer) { 
    Meteor.startup(function() { 
     if (Coll.find().count() === 0) { 
      var f = ["foo","bar"]; 
      for (var i = 0; i < f.length; i++) 
       Coll.insert({f: f[i]}); 
     } 
    }); 
} 

E t.html file di

<head> 
    <title>test</title> 
</head> 

<body> 
    {{> tpl}} 
</body> 

<template name="tpl"> 
    Test tpl 
</template> 
+0

È perché la tua raccolta non è ancora stata caricata. 'Template.rendered' è attivato, non significa che la tua collezione è stata caricata. controlla [questo] (http://stackoverflow.com/questions/15129827/) thread. –

risposta

5

Meteor è costruito fuori da una struttura di tipo data-on-the-wire ri. Ciò significa che quando l'app carica inizialmente l'HTML & JS viene inviato per primo e i dati successivamente.

È necessario utilizzare la reattività per verificare la presenza di modifiche ai dati o controllare quando la sottoscrizione a una raccolta è completa (che comporta la rimozione del pacchetto autopublish). (È possibile controllare come spostare la vostra applicazione per un abbonamento manuale nella documentazione: http://docs.meteor.com/#publishandsubscribe)

Il callback di sottoscrizione indica quando i dati vengono restituiti:

Meteor.subscribe("coll", function() { 
    //Data subscription complete. All data is downloaded 
}); 

Un modello può anche essere fatta reattiva (come il modo in cui stai facendo) ma .rendered non viene chiamato perché Meteor prima controlla se l'html di un modello è cambiato & solo se è diverso cambierà il suo HTML e chiamerà il callback reso.

Quello che hai come opzione è quella di 1) utilizzare Deps.autorun, invece, o

2) Io non so perché si sta utilizzando questo nella vostra callback reso ma se è necessario metterlo lì si è necessario assicurarsi che l'HTML del modello cambi, introducendo qualcosa nel file html della tua raccolta che lo modifica quando vengono introdotti i nuovi dati.

+0

Anch'io sono bloccato qui. Puoi approfondire questo? Sto provando a eseguire manualmente il rendering di un modello che genera un grafico c3 js e sto provando a caricare i dati dal database ma ottenendo l'array vuoto come sopra. – radtek

+0

@radtek Meteor funziona inviando prima l'html, quindi i dati in seguito. Quando viene attivato il callback reso, i dati potrebbero non essere o potrebbero essere stati inviati. Devi fare qualcosa per assicurarti di aspettare che arrivi usando uno dei metodi sopra descritti o il comando 'subscribe ('..'). Wait()' di un router prima di disegnare il tuo grafico. – Akshat

+0

Sì, questo lo so molto. Credo che quello che sto cercando sia un esempio del pacchetto di meteore c3 js in uso. Funziona bene con i dati statici ma dovrebbe esserci un esempio di best practice per lavorare con i dati db. Vedrò cosa ne uscirò più tardi stasera. Quando ho provato a renderizzare l'html e poi a iscrivermi e a mettere fuori i dati tramite i manubri, ho provato a generare uno script js all'interno del modello stesso ma i manubri creerebbero una nuova riga quando ne ho fatto uno per ciascuno, quindi non è stato nemmeno analizzabile js. var data = []; data.push ({{each_item}}); . Quindi ho pensato che fosse troppo hacky e ci fosse bisogno di un modo migliore – radtek

Problemi correlati