2013-05-16 67 views
2

有沒有什麼辦法可以找到調用手動訂閱的observable屬性的名稱?如何檢測在手動訂閱中調用的observable屬性

在淘汰賽中的回調簽名是.subscribe(function(newValue) { ... }),但由於我訂閱了一個對象的所有可觀察屬性,我想要有這樣的簽名:function(newValue, propertyName)(可能還有一箇舊值...)。

下面的代碼提取顯示了我試圖在屬性周圍獲得一個閉包,但它總是在最後一個屬性被掃描時出現。

我怎樣才能找出哪個屬性發生了變化?

this.Data = ko.mapping.fromJS(dataFromServer); 

...

ScrollDataItem.prototype.GetInformedOnChange = function() { 
    var self = this; 
    for(var prop in this.Data) { 
     if(self.Data.hasOwnProperty(prop) && prop != "__ko_mapping__") { 
      var closureProp = prop; 
      self.Data[prop].subscribe(function (newValue) { 
       alert("New value is: " + newValue); 
       alert("Property that called: " + closureProp); 
      }); 
     } 
    } 
}; 

回答

1

你看到這種情況的原因是因爲提升(http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/)的。您聲明的closureProp變量的作用域爲GetInformedOnChange函數。 javascript中的變量始終限定爲該函數的範圍,而不是forwhile循環。

讓我們來看看你所看到的。

假設您在此有兩個屬性:數據:名字和姓氏。第一次通過for(var prop in this.Data)循環時,prop是FirstName,因此給closureProp分配名字。預訂設置完成,但是closureProp尚未用於任何事情,因爲您訂閱的內容尚未觸發。

第二次通過循環時,closureProp(同一個變量 - 不會創建新變量 - 請參閱上面關於提升的鏈接)分配給LastName,然後設置LastName的訂閱。

然後,假設FirstName訂閱被觸發,您的匿名函數被調用來執行警報。它使用了被分配給LastName的closureProp。

您可以通過添加一個額外的範圍界定層來解決這個問題,即額外的功能。這裏是如何:

創建一個新的函數來處理,可提供範圍的額外層訂閱:

function subscribeWithName(propName, observable) { 
    var closureProp = propName; 
    observable.subscribe(function(newValue) { 
     alert("New value is: " + newValue); 
     alert("Property that called: " + closureProp); 
    }); 
} 

調用此函數來設置訂閱:

for(var prop in this.Data) { 
    if(self.Data.hasOwnProperty(prop) && prop != "__ko_mapping__") { 
     subscribeWithName(prop, self.Data[prop]);    
    } 
} 

這裏是一個小提琴:http://jsfiddle.net/tlarson/PfaD7/

+0

晶圓廠 - 這是伎倆!謝謝 – Marcel

+0

如果是這樣,請將此標記爲正確答案? – CodeThug

相關問題