2013-09-04 15 views
17
Todos.TodoController = Ember.ObjectController.extend({ 
    isCompleted: function(key, value){ 
    var model = this.get('model'); 

    if (value === undefined) { 
     // property being used as a getter 
     return model.get('isCompleted'); 
    } else { 
     // property being used as a setter 
     model.set('isCompleted', value); 
     model.save(); 
     return value; 
    } 
    }.property('model.isCompleted') 
}); 

Sto lavorando attraverso la guida ToDo per Ember.js e non riesco a capire come funziona questo controller. Cosa significa .property()? E come mai quando rimuovo il "valore di ritorno"? linea la funzionalità rimane la stessa. Se qualcuno potesse spiegare esattamente cosa sta succedendo qui sarebbe fantastico.Cosa fa .property()? in function() {}. property()

Link alla guida: http://emberjs.com/guides/getting-started/marking-a-model-as-complete-incomplete/

+2

http://emberjs.com/guides/object-model/computed-properties/ –

+1

@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

+0

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

risposta

18

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

+0

Ok grazie! Sto iniziando a capire meglio. Quindi, come mai nell'esempio della domanda originale la chiave dipendente '' model.isCompleted'' e non solo ''isCompleted''? – Wilfred

+0

La confusione è dovuta al fatto che il nome è quasi lo stesso, ma si riferisce a due proprietà diverse. 'isCompleted' dipende da' model.isCompleted', e se usiamo 'isCompleted: function() {...} .property ('isCompleted')', farà riferimento alla proprietà stessa. –

5

.property() segna la funzione come una proprietà calcolata in modo che possa essere utilizzato nei modelli, per esempio, in modo coerente. È una proprietà JavaScript foo? O è una funzione foo()? Le proprietà calcolate risolvono questo problema su tutte le piattaforme.

I campi e i percorsi passati come argomenti sono le chiavi dipendenti . Tutte le proprietà calcolate in Ember vengono memorizzate nella cache per impostazione predefinita. Per sapere quando una proprietà calcolata deve essere ricalcolata, Ember ha bisogno di sapere quali proprietà e percorsi dipende. Nell'esempio della guida, la proprietà calcolata fullName dipende da firstName e da lastName; Ember ha bisogno di sapere che così può ricalcolare fullName quando uno di questi cambia. (Nota: è possibile disattivare la memorizzazione nella cache utilizzando .property().volatile().)

Leggere le guide. Tutto questo è documentato lì.

+0

Quindi nel modello c'è '

  • {{input type =" checkbox "checked = isCompleted class =" toggle "}}
  • 'e l'unica ragione per cui questo funziona è perché isCompleted ha una .property() alla fine? – Wilfred

    +0

    In parte, sì. E le chiavi dipendenti sono ciò che consente a Ember di tenerlo aggiornato. –

    +0

    la sezione delle proprietà calcolate di 2.16.0 non contiene nulla su '.property()' sebbene https://guides.emberjs.com/v2.16.0/object-model/computed-properties/ –

    Problemi correlati