Knockout.js 如何检测手动订阅中调用的可观察属性

Knockout.js 如何检测手动订阅中调用的可观察属性,knockout.js,Knockout.js,我有没有办法找到称为手动订阅的可观察属性的名称 knockout中的回调签名是.subscribe(function(newValue){…}),但由于我订阅了对象的所有可观察属性,我希望有这样一个签名:function(newValue,propertyName)(可能还有一个旧值…) 下面的代码摘录显示了我试图对属性进行闭包,但它总是在最后一次扫描属性时出现 我怎样才能知道哪些属性已更改 this.Data = ko.mapping.fromJS(dataFromServer); 您之所

我有没有办法找到称为手动订阅的可观察属性的名称

knockout中的回调签名是
.subscribe(function(newValue){…})
,但由于我订阅了对象的所有可观察属性,我希望有这样一个签名:
function(newValue,propertyName)
(可能还有一个旧值…)

下面的代码摘录显示了我试图对属性进行闭包,但它总是在最后一次扫描属性时出现

我怎样才能知道哪些属性已更改

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


您之所以看到这一点,是因为吊装()。声明的closureProp变量的作用域是GetInformedOnChange函数。javascript中的变量总是限定在函数范围内,而不是
for
while
循环

让我们看看你看到的

假设您在这个.Data中有两个属性:FirstName和LastName。第一次通过
for(此.Data中的var prop)
循环时,prop是FirstName,因此closureProp被指定为FirstName。订阅已设置,但closureProp尚未用于任何用途,因为您订阅的内容尚未触发

第二次执行循环时,closureProp(相同的变量-未创建新变量-请参阅上面的链接)被分配给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]);            
    }
}
这是一把小提琴:

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