有什么方法可以找出调用手动订阅的可观察属性的名称吗?
淘汰赛中的回调签名是.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);
});
}
}
};
答案 0 :(得分:1)
您看到这个的原因是因为提升(http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/)。您声明的closureProp变量的作用域是GetInformedOnChange函数。 javascript中的变量始终作用于函数,而不是for
或while
循环。
让我们来看看你所看到的。
假设this.Data中有2个属性:FirstName和LastName。第一次通过for(var prop in this.Data)
循环时,prop是FirstName,因此为closureProp分配了名字。订阅已设置,但closesProp尚未用于任何事情,因为您订阅的内容尚未触发。
第二次进行循环时,closesProp(同一个变量 - 未创建新变量 - 请参阅上面的提升链接)被分配给LastName,然后设置了LastName的订阅。
然后,假设触发了FirstName订阅,则会调用您的匿名函数来执行警报。它使用closureProp,它被分配给LastName。
您可以通过添加额外的范围层来解决此问题,即额外的功能。方法如下:
创建一个新函数来处理订阅,提供额外的范围层:
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]);
}
}