2012-11-01 9 views
8

Więc staram się dynamicznie dodawać tych metod obserwacyjnych do obiektu ember.jsjak dynamicznie dodać metody obserwatora do obiektu ember.js

holderStandoutCheckedChanged: (-> 
    if @get("controller.parent.isLoaded") 
     @get("controller").toggleParentStandout(@get("standoutHolderChecked")) 
).observes("standoutHolderChecked") 

holderPaddingCheckedChanged: (-> 
    if @get("controller.parent.isLoaded") 
     @get("controller").toggleParentPadding(@get("holderPaddingChecked")) 
).observes("holderPaddingChecked") 

holderMarginCheckedChanged: (-> 
    if @get("controller.parent.isLoaded") 
     @get("controller").toggleParentMargin(@get("holderMarginChecked")) 
).observes("holderMarginChecked") 

Mam ten kod tak daleko, ale funkcję item.methodToCall nie nazywa się

methodsToDefine = [ 
    {checkerName: "standoutHolderChecked", methodToCall: "toggleParentStandout"}, 
    {checkerName: "holderPaddingChecked", methodToCall: "toggleParentPadding"}, 
    {checkerName: "holderMarginChecked", methodToCall: "toggleParentMargin"} 
] 

add_this = { } 

for item in methodsToDefine 
    add_this["#{item.checkerName}Changed"] = (-> 
     if @get("controller.parent.isLoaded") 
      @get("controller")[item.methodToCall](@get(item.checkerName)) 
    ).observes(item.checkerName) 

App.ColumnSetupView.reopen add_this 

Czy ktoś może mi powiedzieć, co robię źle? Czy jest lepszy sposób to zrobić? Czy powinienem to robić w mixin? Jeżeli tak, proszę

Odpowiedz

17

Nie znam dokładnej przypadku użycia, ale jak pan powiedział, Twój opisany problem może być rozwiązany za pomocą wstawek, zobacz http://jsfiddle.net/pangratz666/a3Usx/

JavaScript:

App = Ember.Application.create(); 

var methodsToDefine = [ 
    {checkerName: "standoutHolderChecked", methodToCall: "toggleParentStandout"}, 
    {checkerName: "holderPaddingChecked", methodToCall: "toggleParentPadding"}, 
    {checkerName: "holderMarginChecked", methodToCall: "toggleParentMargin"} 
]; 

App.Stalker = Ember.Mixin.create({ 
    init: function() { 
    this._super(); 
    methodsToDefine.forEach(function(config) { 
     // add an observer for checkerName - a change should call methodToCall 
     Ember.addObserver(this, config.checkerName, this, config.methodToCall); 
    }, this); 
    }, 

    willDestroy: function() { 
    this._super(); 

    // since we are good citizens, we remove the observers when the object is destroyed 
    methodsToDefine.forEach(function(config) { 
     Ember.removeObserver(this, config.checkerName, this, config.methodToCall); 
    }, this); 
    } 
}); 

Przykładowy przypadek użycia:

var myObj = Ember.Object.create(App.Stalker, { 
    toggleParentStandout: function() { 
    console.log("toggleParentStandout called"); 
    }, 
    toggleParentPadding: function() { 
    console.log("toggleParentPadding called"); 
    }, 
    toggleParentMargin: function() { 
    console.log("toggleParentMargin called"); 
    } 
}); 

myObj.set('standoutHolderChecked', 42); 
myObj.set('holderPaddingChecked', 'Buster'); 

Kolejna realizacja byłaby mixin który wykorzystuje tablicę watchProperties, czyli wykaz właściwości, które powinny być przestrzegane, zobacz http://jsfiddle.net/pangratz666/bSF3Z/:

JavaScript:

App = Em.Application.create(); 

App.Stalker = Ember.Mixin.create({ 
    init: function() { 
    this._super(); 

    var props = this.get('watchProperties'); 
    Ember.assert("watchProperties should be an array", Ember.isArray(props)); 
    props.forEach(function(property) { 
     // invoke <property>Changed when <property> changes ... 
     Ember.addObserver(this, property, this, '%@Changed'.fmt(property)); 
    }, this); 
    }, 

    willDestroy: function() { 
    this._super(); 

    this.get('watchProperties').forEach(function(property) { 
     Ember.removeObserver(this, property, this, '%@Changed'.fmt(property)); 
    }, this); 
    } 
}); 

var o = Ember.Object.create(App.Stalker, { 
    // 'a b'.w() == ['a', 'b'] 
    watchProperties: 'a b'.w(), 
    aChanged: function() { 
    console.log("a changed"); 
    } 
}); 

o.set('a', 123); 
+0

wow pangratz co za amazining odpowiedź dzięki dużo. –

+0

rozwiązuje to dla mnie wiele problemów, dziękuję. próbował dowiedzieć się, jak obserwować 'fields. @ each.value', bez konieczności przechodzenia przez tablicę, aby dowiedzieć się, co się zmieniło. to pozwala mi robić rodzaj proxy, który pozwala dynamicznym obiektom pola formularza komunikować się z bardzo odmiennym modelem. – jrode

Powiązane problemy