in javascript l'unico modo per fare un po 'di elaborazione quando ottenere o impostare una proprietà sta usando Object.defineProperty:
Object.defineProperty(person, "b", {
get : function() {
return person.firstName + ' ' + person.surname;
},
set : function(newValue) {
var names = newValue.split(' ');
person.firsname = names[0];
person.surname = names[1];
},
enumerable : true,
configurable : true
});
Ma questo hanno alcuni svantaggi:
- non è cross browser
- Non ha vincoli, in altre parole, se le modifiche sono
firstname
o surname
, la proprietà dipendente fullname
non viene modificata.
- Calling
person.name
quando person
è indefinito, fare un errore per essere gettato
- non è possibile innescare osservatori, non senza codice aggiuntivo e consapevole della gerarchia depency:
firstname
dipende da fullname
, e può essere la dipendenza degli altri proprietà arghhh!
A causa di questo Ember ha il concetto di "proprietà", chiamato computed property.
Può essere dichiarata in 2 modi:
foo: Ember.computed(function({
...
}).property(dependent keys);
o quando si utilizza (di default) Ember.ENV.EXTEND_PROTOTYPES = true
:
foo: function() {
...
}.property(dependent keys);
Il property(dependent keys)
, è necessaria perché si dice di Ember qual è il properies che una volta modificato, renderà la proprietà aggiornata.
fullname: function(key, value) {
// setter
if (value !== undefined) {
var names = value.split(' ');
this.set('firstname', names[0]);
this.set('surname', names[1]);
}
// always return the complete result, so nexts calls to this.get('fullname') will return the cached value
return this.get('firstname') + ' ' + this.get('surname');
}.property('firstname', 'surname')
Usando questo, si ha il vantaggio di:
- quando si cambia
firstname
o surname
ad un nuovo valore, fullname
viene modificato.
- Gli
beforeObserves
vengono attivati prima di modificare il valore e observes
vengono attivati dopo la modifica del valore.
- Qualsiasi modello che fa riferimento a una proprietà viene aggiornato
- Più di una chiamata a person.get ('firstname'), restituirà un valore memorizzato nella cache, salvando l'elaborazione. È possibile disattivare questo utilizzando
.property(..).volatile()
- Evitare errori nulli o non definiti, quando si accede a oggetti nulli come:
controller.get('person.dog.name')
restituisce undefined
, se persona o cane non è definito.
Spero che aiuta
fonte
2013-09-04 14:08:07
http://emberjs.com/guides/object-model/computed-properties/ –
@RUJordan io continuo a non capire perché è necessario .property() in questo codice 'fullName: function() { return this.get ('firstName') + '' + this.get ('lastName'); } .property ('firstName', 'lastName') 'sembra ancora ridondante avere sia un ritorno e un .property() – Wilfred
Anche in questo pezzo di codice' App.SongsController = Ember.ArrayController.extend ({ longSongCount : function() { var longSongs = this.filter (function (song) { return song.get ('duration')> 30; }); return longSongs.get ('length'); } .property ('@ each.duration') }); 'Stai già restituendo la lunghezza dei LongSongs, quindi perché hai bisogno .property ('@ each.duration')? – Wilfred