2012-07-29 11 views
5

stavo cercando di rispondere a questa domanda: emberjs: add routes after app initialize()Giocare con Ember.Object.reopen(), perché ho quei risultati?

ho iniziato a giocare con Ember.Object.reopen(), per capire come funziona, e forse trovare un modo di rispondere alla domanda precedente.

mi sento un po 'perplesso, e non capisco il comportamento di questo codice:

jsfiddle: http://jsfiddle.net/Sly7/FpJwT/

<script type="text/x-handlebars"> 
    <div>{{App.myObj.value}}</div> 
    <div>{{App.myObj2.value}}</div> 
    <div>{{App.myObj3.value}}</div> 
</script> 
App = Em.Application.create({}); 

App.MyObject = Em.Object.extend({value: 'initial'}); 

App.set('myObj', App.MyObject.create()); 

Em.run.later(function(){ 
    App.get('myObj').reopen({ 
    value: "reopenOnInstance"   
    }); // the template is not updated, 'initial' is still diplayed, but 
    console.log(App.get('myObj').get('value')); // print 'reopenOnInstance' 

    App.MyObject.reopen({ 
    value: "reopenOnClass"  
    }); 
    App.set('myObj2',App.MyObject.create()); // the template is updated and 
    console.log(App.get('myObj2').get('value')); //print 'reopenOnClass' 

    App.myObj3 = App.MyObject.create(); // the template is not updated but 
    console.log(App.myObj3.get('value')); // print 'reopenOnClass' 

    Em.run.later(function(){ 
    App.get('myObj').set('value', "setWithSetter"); // the template is updated and 
    console.log(App.get('myObj').get('value')); // print 'setWithSetter' 

    App.get('myObj2').set('value', "setWithSetter"); // the template is updated and 
    console.log(App.get('myObj2').get('value')); // print 'setWithSetter' 

    App.myObj3.set('value', "setWithSetter"); // the template is not updated but 
    console.log(App.myObj3.get('value')); // print 'setWithSetter' 

    }, 2000); 
},2000); 

Se qualcuno può spiegare che cosa sta succedendo, soprattutto perché il i modelli a volte non sono aggiornati, a volte aggiornati, e anche qual è la differenza tra chiamare reopen su una classe, chiamandolo e su un'istanza.

risposta

5

Non sicuro al 100%, ma proverò a rispondere alle vostre domande.

Per prima cosa dare un'occhiata a "myObj3". I metodi getter/setter ember attivano gli aggiornamenti nei template (attivano eventi interni che fanno sì che ogni proprietà/osservatore sappia che qualcosa è successo). L'impostazione di un valore a mano semplicemente aggiorna il valore ma non attiva questi eventi e quindi non cambia nulla nell'interfaccia utente. Un po 'come quando si utilizza un elenco Mutabile si utilizza pushObject per assicurarsi che gli aggiornamenti dell'interfaccia utente.

Ora guardiamo il vostro "riaprire". Quando si riapre sulla classe funziona come ci si aspetterebbe e si aggiorna la classe base. Quando si riapre un'istanza, in realtà si sta creando un mixin e lo si sovrappone all'oggetto. Ciò significa che quando esegui un "get" emer itera sopra l'oggetto mixin & per il valore da restituire. Trova che mescola e ottiene il valore prima dell'oggetto; potresti effettivamente sostituire il metodo con un "return" pippo + this._super() "nell'istanza avrai" pippo iniziale "(pensa che il tuo oggetto abbia strati come una cipolla). Se hai un gruppo di mixin sopra il tuo oggetto, ti sarà difficile trovare il valore corretto se imposti qualcosa direttamente (ma "get" funzionerà perfettamente). Questo porta alla regola generale che si dovrebbe sempre usare "set" invece di un riferimento diretto.

Nota a margine: è possibile chiamare "getPath" anziché "get" ed è possibile utilizzare il percorso relativo o assoluto. Ad esempio App.getPath ('myObj2.value') che renderà il codice un po 'più facile da gestire. Va anche per "setPath".

Infine: l'ultimo valore viene stampato perché è stato modificato il valore (è lì) ma il trigger per ember per aggiornare l'interfaccia utente non viene mai attivato perché non è mai stato impostato sull'oggetto "myObj3".

MODIFICA: nella versione più recente di ember sembra che la riapertura su un'istanza esegua un'operazione di unione sull'oggetto (se tale chiave esiste già). Il mixin si concluderà solo se aggiungi nuovi contenuti.

+0

Tutto ha senso. Grazie mille mi hai illuminato. Quindi, se capisco bene, riaprire un'istanza come faccio qui, ha lo stesso comportamento di "App.get ('myObj'). Value = 'reopenOnInstance'' giusto? Ero a conoscenza di getPath, metodo, e ora con l'ultimo ember, il comando get ha lo stesso comportamento, si può fare 'obj.get ('otherObj.someProperty')'. –

+0

Vedi modifica. Ciò significa che sei corretto, l'impostazione diretta del valore sarà proprio come la riapertura di un'istanza. Ma se hai qualcosa che si lega a quel valore (come l'interfaccia utente) Ember genererà un errore perché "set" non è stato usato (fatto un [violinista] (http://jsfiddle.net/scispear/n5B5d/) per vedere il errore). – SciSpear

+0

Grazie ancora per la modifica :). Penso che ora la risposta sia completa in quanto non ho più nulla da chiarire. –

Problemi correlati