2012-05-02 25 views
12

Qualcosa che trovo molto contro-intuitivo su Ember è che è possibile sovrascrivere una funzione di setter di proprietà calcolata (http://emberjs.com/#toc_computed-properties-setters) con gli argomenti su create(). Vedo http://jsfiddle.net/zJQJw/2/Perché gli argomenti per create() non si comportano più come setProperties()?

ho trovato la migliore soluzione per questo è di chiamare create().setProperties(properties) invece di create(properties), ma questo sembra un Gotcha inutile per me. Mi rendo conto che potrebbe interrompere alcune app a questo punto, ma penseresti che il comportamento create() si comporti più come setProperties()?

La mia motivazione per chiedere questo è che init() verrà chiamato prima dello setProperties() quando si utilizza il modello create().setProperties(properties). Questo non è stato ancora un grosso problema, ma posso vedere che questo è indesiderabile in alcune situazioni. Questo è un esempio completamente inventato, ma forse puoi vedere a cosa sto arrivando? http://jsfiddle.net/QJ8vX/2/

L'unica ragione che posso vedere per mantenere il comportamento corrente è eseguire sovrascrizioni specifiche dell'istanza dei metodi setter. Ma in questi casi lo si potrebbe facilmente fare MyClass.extend({ overridenMethod: ... }).create(properties)

Una modifica come questa può essere considerata per Ember 1.0? O ho solo un'idea sbagliata su come dovrebbe funzionare il modello di oggetti di Ember?

+0

io feci salire questo numero esatto nel canale, per lo più accademico, e la risposta è stata (parafrasando) "Non vedo noi cambiare il comportamento di creare." Ti incoraggerei comunque ad aprire un problema di discussione su github. –

+1

Ho archiviato https://github.com/emberjs/ember.js/issues/777, quindi sentitevi liberi di suonare lì. –

+0

un paio di noi qui ha anche discusso con il team di ember anche su questo, e sostanzialmente hanno detto che non lo stanno cambiando. Sono d'accordo con te. –

risposta

10

Il motivo principale per cui abbiamo respinto questa modifica è che rende impossibile sovrascrivere le proprietà definite sulle classi base come proprietà calcolate. Ad esempio, nel Ember.View, la proprietà template è una proprietà calcolata:

template: Ember.computed(function(key, value) { 
    if (value !== undefined) { return value; } 

    var templateName = get(this, 'templateName'), 
     template = this.templateForName(templateName, 'template'); 

    return template || get(this, 'defaultTemplate'); 
}).property('templateName').cacheable(), 

Quando si crea una sottoclasse di Ember.View, è possibile ignorare questa definizione di una funzione di modello esplicito:

Ember.View.create({ template: Ember.Handlebars.compile('...') }); 

Se il la proprietà calcolata non gestisce il caso setter, questo tentativo di sovrascrivere la proprietà calcolata sarebbe un errore non presidiato.

Se abbiamo apportato questa modifica, introduce anche altre domande sull'attivazione degli osservatori per le proprietà passate nel metodo create. Entrambi sono possibili da attuare e ci sono forti argomentazioni per entrambi gli approcci.

Nella corsa fino a 1,0, sembra ragionevole considerare un approccio che possa:

  • cambiamento create utilizzare setProperties semantica
  • aggiungere una nuova API (override o createWithOverride) che manterrebbe la semantica esistente, nel caso in cui si desideri eseguire l'override delle proprietà calcolate esistenti
  • osservatori di soppressione per le proprietà impostate a causa di create (o decidere di non)
  • trovare un modo per rilevare e avvertire sui tentativi di utilizzare l'API create con proprietà calcolate che non implementano i setter.

avrei bisogno di discutere più, e prendere in considerazione le implicazioni per applicazioni esistenti, ma è sicuramente qualcosa da prendere in considerazione, in quanto è sicuramente una abbastanza grande Gotcha per i nuovi sviluppatori.Il fatto che abbiamo dovuto modificare il comportamento per ember-data è un buon indizio che qualcosa non è giusto.

+1

Mi piacerebbe sapere se si tratta dello stesso tipo di problema come http://stackoverflow.com/questions/11412550/observer-are-not-called-on-create –

+0

Grazie per la risposta dettagliata, Yehuda. Sono interessato a vedere come questo potrebbe essere risolto in una versione futura. Le pallottole che hai elencato sembrano promettenti. –

+0

Si applica solo alla versione 1.0. 'create()' è stato modificato per utilizzare 'setProperties()' [qui] (https://github.com/emberjs/ember.js/commit/c1c720781c976f69fd4014ea50a1fee652286048). La nuova API che usa la vecchia semantica è 'createWithMixins()'. –

4

Potrebbe essere un trucco sporco, ma funziona per me.

Em.Object.reopenClass({ 
    create: function(config) { 
     return this._super().setProperties(config); 
    } 
}); 
+0

Hm, questo è il mio tipo di hack. Implementazione. –

Problemi correlati