如何使用 KnockoutJS 更改全局 属性 事件处理程序
How to have a global property changed event handler with KnockoutJS
我来自 C# 环境,那里有 INotifyPropertyChanged 接口。当订阅此 属性 更改事件时,会收到发件人和 属性 名称。发件人是本例中的 ViewModel。我想要与 KnockoutJS 类似的东西。我尝试将函数的实例订阅并存储到一个哈希表中,该哈希表包含一个带有 ViewModel 和 PropertyName 参数的对象。因为可观察对象中的新值不足以满足我要使用该事件的目的。
如何使用 KO 创建与 C# 的 INotifyPropertyChanged 工作方式类似的代码?
这是我为了向您展示我付出了一些努力而写的废话。但我在这里惨遭失败。
var propertyChangedHashTable = new Hashtable();
function PropertyChanged(newValue) {
console.log(this);
var changedEventParams = propertyChangedHashTable[this];
console.log(changedEventParams);
//gateway.propertyChanged(changedEventParams.viewModel, changedEventParams.propertyName, newValue);
};
function subscribePropertyChanged(viewModel, objectPath) {
if (typeof objectPath === "undefined" || objectPath == null) objectPath = "";
if (objectPath.length !== 0) objectPath += '.';
var observable = ko.observable("").toString();
for (var propertyName in viewModel) {
var viewModelName = viewModel.__proto__.constructor.name;
var localObjectPath = objectPath + viewModelName;
var property = viewModel[propertyName];
if (propertyName.indexOf("ViewModel") !== -1) {
subscribePropertyChanged(property, localObjectPath);
continue;
}
var isObservable = property.toString() === observable.toString();
if (!isObservable) continue;
var propertyChangedFunc = PropertyChanged;
propertyChangedHashTable.put(propertyChangedFunc, 'test');
property.subscribe(propertyChangedFunc);
}
}
function MainViewModel() {
var self = this;
self.isRecording = ko.observable(false);
self.dataDirectory = ko.observable("C:\Temp\Recordings");
self.toggleIsRecording = function() {
self.isRecording(!self.isRecording());
};
}
var viewModel = new MainViewModel();
subscribePropertyChanged(viewModel);
来自淘汰赛docs:
The subscribe function accepts three parameters: callback is the function that is called whenever the notification happens, target (optional) defines the value of this in the callback function, and event (optional; default is "change") is the name of the event to receive notification for.
因此,如果您将 ViewModel 作为第二个参数 "target" 提供给 subscribe()
,您可以在处理程序中以 this
的形式访问它。例如:
<p data-bind="text: counter"></p>
<button data-bind="click: buttonClicked">Increment</button>
<script type="text/javascript">
var ViewModel = function() {
this.counter = ko.observable(0);
this.buttonClicked = function() {
this.counter(this.counter() + 1);
};
this.counter.subscribe(function(newValue) {
console.log(newValue);
console.log(this);
}, this);
};
ko.applyBindings(new ViewModel());
</script>
我来自 C# 环境,那里有 INotifyPropertyChanged 接口。当订阅此 属性 更改事件时,会收到发件人和 属性 名称。发件人是本例中的 ViewModel。我想要与 KnockoutJS 类似的东西。我尝试将函数的实例订阅并存储到一个哈希表中,该哈希表包含一个带有 ViewModel 和 PropertyName 参数的对象。因为可观察对象中的新值不足以满足我要使用该事件的目的。
如何使用 KO 创建与 C# 的 INotifyPropertyChanged 工作方式类似的代码?
这是我为了向您展示我付出了一些努力而写的废话。但我在这里惨遭失败。
var propertyChangedHashTable = new Hashtable();
function PropertyChanged(newValue) {
console.log(this);
var changedEventParams = propertyChangedHashTable[this];
console.log(changedEventParams);
//gateway.propertyChanged(changedEventParams.viewModel, changedEventParams.propertyName, newValue);
};
function subscribePropertyChanged(viewModel, objectPath) {
if (typeof objectPath === "undefined" || objectPath == null) objectPath = "";
if (objectPath.length !== 0) objectPath += '.';
var observable = ko.observable("").toString();
for (var propertyName in viewModel) {
var viewModelName = viewModel.__proto__.constructor.name;
var localObjectPath = objectPath + viewModelName;
var property = viewModel[propertyName];
if (propertyName.indexOf("ViewModel") !== -1) {
subscribePropertyChanged(property, localObjectPath);
continue;
}
var isObservable = property.toString() === observable.toString();
if (!isObservable) continue;
var propertyChangedFunc = PropertyChanged;
propertyChangedHashTable.put(propertyChangedFunc, 'test');
property.subscribe(propertyChangedFunc);
}
}
function MainViewModel() {
var self = this;
self.isRecording = ko.observable(false);
self.dataDirectory = ko.observable("C:\Temp\Recordings");
self.toggleIsRecording = function() {
self.isRecording(!self.isRecording());
};
}
var viewModel = new MainViewModel();
subscribePropertyChanged(viewModel);
来自淘汰赛docs:
The subscribe function accepts three parameters: callback is the function that is called whenever the notification happens, target (optional) defines the value of this in the callback function, and event (optional; default is "change") is the name of the event to receive notification for.
因此,如果您将 ViewModel 作为第二个参数 "target" 提供给 subscribe()
,您可以在处理程序中以 this
的形式访问它。例如:
<p data-bind="text: counter"></p>
<button data-bind="click: buttonClicked">Increment</button>
<script type="text/javascript">
var ViewModel = function() {
this.counter = ko.observable(0);
this.buttonClicked = function() {
this.counter(this.counter() + 1);
};
this.counter.subscribe(function(newValue) {
console.log(newValue);
console.log(this);
}, this);
};
ko.applyBindings(new ViewModel());
</script>