2012-12-08 14 views
6

Ho un problema durante l'esecuzione con Meteor.Modello Meteor ricarica infinito

Ho una pagina "domanda" che voglio aumentare la visualizzazione del conteggio ogni volta che viene visualizzato.

Così nella mia funzione template scrivo

Template.questionview.helpers({ 
    question : function() { 
     if(Session.equals('main_template_name', 'question')) { 
     console.log(Session.get('question_id')); 
     Questions.update({ 
      _id: Session.get('question_id') 
     }, { 
      $inc: { 
      views: 1 
     } 
    }); 
    } 
}); 

Ora qui viene il problema, quando mi rendo la vista domanda e aggiornare l'elemento domanda, la vista viene aggiornata di nuovo perché è una pagina di riflettente. E poi arriva il ciclo infinito.

Chiunque ha suggerimenti?

risposta

4

Tipicamente, in situazioni come questa, c'è qualcosa di rotto nel modello. In questo caso, credo che sia l'idea della "vista di conteggio". Ci sono molti modi per farlo correttamente. Incrementarlo sul rendering non lo è, dal momento che stai facendo il lavoro sul modello nel codice UI (rotto concettualmente e in fase di implementazione).

Per prima cosa, memorizza le domande che l'utente ha visitato da qualche parte. Perché non una proprietà {questionsVisited:[]} per l'utente?

utilizzare una chiamata Meteor.call(...) metodo per registrare una vista invece:

Meteor.methods({ 
    viewQuestion: function(questionId) { 
    // check if the user hasn't visited this question already 
    var user = Meteor.users.findOne({_id:this.userId,questionsVisited:{$ne:questionId}}); 

    if (!user) 
     return false; 

    // otherwise, increment the question view count and add the question to the user's visited page 
    Meteor.users.update({_id:this.userId},{$addToSet:{questionsVisited:questionId}}); 
    Questions.update({_id:questionId},{$inc:{views:1}}); 
    return true; 
}); 

Così come su incrementando la vista sui cambiamenti dell'interfaccia utente? Bene, non lo facciamo in modo specifico. Aumentiamo il numero di visualizzazioni solo quando la domanda cambia.

Meteor.autorun(function() { 
    var questionId = Session.get("question_id"); 
    Meteor.call('viewQuestion',questionId,function(e,r) { 
    if (r) 
     console.log("Question " + questionId + " logged an increment."); 
    else 
     console.log("Question " + questionId + " has already been visited by user " + Meteor.userId(); 
    }); 
}); 

E sbarazzarsi di tutta questa roba aiutante domanda ...

questo è ancora meglio di quello che in origine voleva. Ora le visualizzazioni non vengono conteggiate due volte per lo stesso utente. Se questo è il comportamento desiderato, rimuovere la logica questionsVisited.

Solo cambiare la variabile di sessione 'question_id' quando si modifica effettivamente la domanda logica con cui l'utente sta lavorando.

+0

Sei brillante. Avrei dovuto registrare user_id visitato in domanda o question_id in utente, come quello che suggerisci. Penso che la tua soluzione sia più pulita. Sono ancora uno studente di Meteor. Posso chiederti perché dovrei sbarazzarmi di cose di supporto. – user857188

0

Piuttosto che inserire un helper, inserisco questa logica nell'evento renderizzato, ad es.

Template.questionview.rendered ... 

Vedere the Meteor docs.

+0

Grazie per l'aiuto. In realtà l'ho provato prima. Comunque è lo stesso. Suppongo che sia perché dopo aver aggiornato la domanda, il modello di questionview verrà nuovamente visualizzato. Una volta eseguito il rendering, la domanda viene aggiornata e così via e così via ... – user857188

+1

Non sono sicuro se c'è un modo per dire a Meteora di non aggiornare la pagina. Voglio dire, forse chiedi a Meteor di non aggiornare di nuovo la vista. – user857188

1

Ho risolto questo problema utilizzando meteor-collection-hooks

Prima installarlo

>_ meteor add matb33:collection-hooks 

Poi nel modello

Questions.after.findOne(function (userId, selector, options, doc){ 
    Questions.update({_id: doc._id},{$inc:{views:1}}); 
}); 

E KABOOM Ecco fatto

0

Se si utilizza pubblica e sub scriba (che sicuramente dovrebbe comunque) si può fare sul vostro metodo di pubblicare come

Meteor.publish('posts', function(id) { 
    Posts.update({_id:id},{$inc:{view:1}}); 
    return Posts.find({_id: id}); 
}); 

o sul tuo iscriviti richiamata

Meteor.subscribe("posts" , id { 
    onReady: function() { Meteor.call("incrementView", id);}}); 

questo modo si incrementa solo il conteggio una volta ogni volta che gli utenti aprono il browser.

Problemi correlati