2013-02-28 18 views
41

Una domanda rapida sul contesto dei gestori di eventi per i modelli in Meteor (con Handlebars).Il contesto di "questo" in gestori di eventi modello Meteor (utilizzando Handlebars per il template)

  • Nella sezione di Documentazione sulle istanze di template (http://docs.meteor.com/#template_inst) si è detto che "Oggetti modello di istanza sono trovati come il valore di questo nel creato, reso, e distrutto callback template e come argomento di evento gestori "
  • Nella sezione Modelli (http://docs.meteor.com/#templates) si dice" Infine, è possibile utilizzare una dichiarazione di eventi su una funzione modello per impostare una tabella di gestori di eventi. il formato è documentato in Event Maps. il presente l'argomento per il gestore dell'evento sarà il contesto dati dell'elemento che ha attivato l'evento. "

Bene, questo è vero solo in parte Facciamo un esempio dalla documentazione:.

<template name="scores"> 
    {{#each player}} 
    {{> playerScore}} 
    {{/each}} 
</template> 

<template name="playerScore"> 
    <div>{{name}}: {{score}} 
    <span class="givePoints">Give points</span> 
    </div> 
</template 
Template.playerScore.events({ 
    'click .givePoints': function() { 
    Users.update({_id: this._id}, {$inc: {score: 2}}); 
    }); 

Qui il 'questo' contesto gestore di eventi il ​​'click .givePoints' è infatti il ​​modello . istanza di playerScore Andiamo a modificare il codice HTML:

<template name="scores"> 
    <span class="click-me">Y U NO click me?<span> 
    {{#each player}} 
    {{> playerScore}} 
    {{/each}} 
</template> 

<template name="playerScore"> 
    <div>{{name}}: {{score}} 
    <span class="givePoints">Give points</span> 
    </div> 
</template> 

... e aggiungere un gestore eventi per .Click-me sul modello punteggi:

Template.scores.events({ 
    'click .click-me': function() { 
    console.log(this); 
    } 
}); 

Ora, se si fa clic sull'intervallo, cosa viene registrato? L'oggetto Window! Cosa mi aspettavo di ottenere? L'oggetto modello! O forse il contesto dei dati, ma non è né l'uno né l'altro. Tuttavia, all'interno dei callback (ad es. Template.scores.rendered = function() {...}) il contesto di "this" è sempre l'istanza del template.

Credo che la mia vera domanda sarebbe: è questo qualcosa a che fare con

  • un bug nel manubrio, meteora o una via di mezzo?
  • documentazione leggermente incompleta sui modelli?
  • mi ha completamente frainteso i documenti o non ho capito qualcosa di fondamentale su Meteor o Manubri?

Grazie!

+6

Questa è una domanda giusta. Ho sempre avuto accesso ai dati negli eventi usando 'function (event, template)', e poi attraverso 'template.data'. – Twark

+0

Vorrei poterlo invitare due volte allo – Ruby

+0

@ ТаняТ. puoi contrassegnare la domanda come preferita, come ho fatto io ;-) – think01

risposta

27

Questo video spiega i concetti:

http://www.eventedmind.com/posts/meteor-spark-data-annotation-and-data-contexts.

La risposta diretta alla sua domanda:

Il thisArg all'interno di un gestore di eventi dovrebbe punto a un contesto dati. Ma a volte il contesto dei dati è undefined. Quando si utilizza lo Function.prototype.call(thisArg, ...) in JavaScript, se thisArg non è definito (ad es.un dataContext non è definito) il browser imposterà this uguale alla finestra. Quindi, i documenti non sono errati di per sé ma il codice di gestione degli eventi non sta proteggendo dalla possibilità di un contesto di dati non definito. Suppongo che sarà risolto in breve tempo.

Quindi, che cosa produce un contesto dati per un modello? Normalmente il tuo modello radice non avrà nemmeno un contesto dati. In altre parole, la funzione Template è chiamata senza un oggetto. Ma se si utilizza l'helper del blocco {{#with o l'iteratore {{#each, verrà creato un contesto di dati per ciascun elemento nell'elenco o, nel caso dello con l'helper, l'oggetto.

Esempio:

var context = {}; 

<template name="withHelper"> 
    {{#with context}} 
    // data context is the context object 
    {{/with}} 
</template> 

var list = [ {name: "one"}, {name: "two"} ]; 

<template name="list"> 
    {{#each list}} 
    {{ > listItem }} // data context set to the list item object 
    {{/each}} 
</template> 
+0

inchiodato, grazie! –

+0

Il contesto dei dati impostato su 'window' se il contesto dei dati non è definito è stato corretto nell'ultima versione di Meteor. Quindi, ora "questo" all'interno di un gestore di eventi punta sempre a un oggetto, sia il contesto dati o un oggetto vuoto se non esiste un contesto dati. – cmather

+1

SI SANGUE SÌ !!!!! –

13

Il primo parametro nella funzione è l'evento. Quindi potresti usare il bersaglio dell'evento per afferrare il tuo elemento.

Template.scores.events({ 
    'click .click-me': function (event, template) { 
    console.log(event.target); 
    $(event.target).text("O but I did!"); 
    } 
}); 
+2

Grazie Brandon. Questo è davvero un modo per afferrare l'elemento (anche se generalmente utilizzerei currentTarget). Tuttavia non risponde alla mia domanda: bug, documenti o me? –

+2

Direi documenti. Esp poiché la meteora è ancora in pre-rilascio. I documenti sono probabilmente la cosa più difficile da tenere aggiornati e per essere pienamente inclusivi. In situazioni come queste, ho appena iniziato ad aggiungere parametri alla funzione e poi alla console per registrarli. es. funzione (param1, param2, param3) {console.log (param1); console.log (param2); console.log (param3);} –

+1

È possibile ottenerli tutti insieme con console.log (argomenti). –

Problemi correlati