2015-03-26 13 views
6

Il dilemma:Meteor: oncreated vs onrendered

  • oncreated: il modello non è stato ancora reso (incendi sola tempo per ogni modello).
  • onrendered: il modello viene visualizzato (si attiva più volte).

È possibile attivare una funzione solo dopo che il modello è stato reso completamente?

Ho un elenco di messaggi, che sembrano simili a questo

<template name="messages"> 
    <div id="messages"> 
     <span class="message">{{this.message}}</span> 
    </div> 
</template> 

Ogni volta che un nuovo messaggio viene inserito nel DOM, voglio sapere se il testo del messaggio contiene il nome utente.

Il seguente frammento di codice viene eseguito più volte, di cui deve essere eseguito solo una volta.

Template.messages.rendered = function() { 

    var username = Meteor.user().services.twitter.screenName; 
    $("#messages").bind("DOMSubtreeModified", function() {  
     var lastmessage = $('.message').last().text(); 
     if (lastmessage.indexOf(username) > -1) { 
      //Do something 
     } 
    } 
} 

Scambiare resi da creato & cambiando il modello di contenere un singolo messaggio, rende la funzione di esecuzione una volta per ogni nuovo messaggio. Ciò significa che prende il penultimo valore per la variabile lastmessage:

Template.message.created = function() { 
    var username = Meteor.user().services.twitter.screenName; 

    var lastmessage = $('.message').last().text();//this is not the last message 
    if (lastmessage.indexOf(username) > -1) { 
     //Do something 
    } 
} 
+1

La [documenti] (http://docs.meteor.com/#/full/template_onRendered) dicono che onRendered generato solo una volta: "richiamate aggiunto con questo metodo sono chiamati una volta quando un'istanza di Template.myTemplate viene reso nei nodi DOM e inserito nel documento per la prima volta. " – foobarbecue

+0

Bene, nel mio caso i nuovi messaggi continuavano ad essere aggiunti al modello e sarebbe stato rerenderizzato per ogni messaggio. Impostare un timeout sembrava l'unica cosa che funzionasse, anche se potrebbe non essere nel libro delle migliori pratiche di Meteor. – Fullhdpixel

+0

@Fullhdpixel non è una buona pratica in javascript o in qualsiasi altro linguaggio di programmazione, per quel caso ... Sta hackerando il tuo codice e se hai hackerato il tuo codice in questo modo, diventerà sempre più difficile mantenere tale codice. Dovresti in qualche modo arrivare in fondo al motivo per cui il tuo onRendered è stato licenziato più volte. – Lukas1

risposta

-2

risolto questo avvolgendo il codice in una funzione setTimeout.

+1

Meteor.defer è utilizzato anche per lo stesso scopo. –

1

Onestamente non potreste fare qualcosa di simile in "rendering". Oppure puoi inserire qualche callback dopo aver reso le tue cose extra nel DOM.

Inoltre, è possibile utilizzare self.autorun(() => { if(self.alreadyRun) return; ... }) e self.alreadyRun = new ReactiveVar(false).

Solo supposizioni!

var self = this; 

self.alreadyRun = false; 
if(self.alreadyRun){ 
    self.alreadyRun = true; 

    // run once code here 

}