淘汰赛订阅范围
Knockout subscribe scope
是否可以更改 Knockout 中的订阅范围?
我有这样的东西:
element =
{
type: ko.observable()
name: ko.observable()
content: ko.observable()
}
element.type.subscribe(this._typeChanged.bind(element))
基本上我想访问我订阅的 属性 对象。像我的代码中那样的绑定不起作用,因为它绑定到整个 VeiwModel 而不是对象。
问题在于您创建视图模型的方式。视图模型应该是自包含的,包括对其进行操作的功能。它应该是这样的:
var ViewModel = function() {
var self = this;
self.type = ko.observable();
self.name = ko.observable();
self.content = ko.observable();
self.type.subscribe(function(newVal) {
// here you have access to all the viewmodel properties through self
});
return self;
};
这是一个使用 var self=this;
pattern.To 的构造函数,使用您需要实例化它的视图模型,即 var vm = new ViewModel()
。 (可以省略new
)。
当然你也可以定义一个函数,绑定到self
,或者在构造函数中接收回调,绑定到self
。在这种情况下,函数实现将通过 this
访问视图模型,而不是 self,后者在函数体内是未定义的。
var doSomethignWithVm = function(newVal) {
// acces viewmodel via this
// you can also use newVal
};
您修改构造函数以将此作为回调接收:
var ViewModel = function(doSomethingCallback) {
self.type.subscribe(callback.bind(self));
};
这种模式没有多大意义,因为您的回调应该知道您的视图模型。在这种情况下,将订阅功能直接包含在模型中更有意义。
编辑
注意:正如我在对 Joel Ramos Michaliszen 的回答的评论中提到的,这两个代码是等效的:
self.type.subscribe(callback.bind(self));
self.type.subscribe(callback.bind, self);
您可以通过在文件 knockout/src/subscribales/subscribable.js
中查看 knockout's gitbhub 中 subscribable
的源代码来检查这一点。如果您寻找订阅实现,您会看到:
subscribe: function (callback, callbackTarget, event) {
// ...
boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
即如果您提供第二个参数,它用于将第一个参数中传递的函数绑定到它。
也许当你订阅一个 observable 时,你可以传递 2 个参数,第一个是 callback,第二个是scope/context,试试这样:
element.type.subscribe(this._typeChanged, element)
subscribe函数接受三个参数:callback是每当通知发生时调用的函数,target(可选)定义回调函数中this的值,event(可选;默认为"change") 是接收通知的事件的名称。
虽然我知道我可能采用了错误的方法,但我也处于无法对应用程序进行任何重大更改的阶段。
我发现我可以使用 lodash 来帮助我解决这个问题。
我最终使用部分函数将元素附加为订阅回调中的参数:
element.type.subscribe(_.partial(this.typeChanged, element))
或在 coffeescript 中
element.type.subscribe $_.partial @typeChanged, element
现在 chartTypeChanged 在输入上有 2 个参数,而不是一个。
是否可以更改 Knockout 中的订阅范围?
我有这样的东西:
element =
{
type: ko.observable()
name: ko.observable()
content: ko.observable()
}
element.type.subscribe(this._typeChanged.bind(element))
基本上我想访问我订阅的 属性 对象。像我的代码中那样的绑定不起作用,因为它绑定到整个 VeiwModel 而不是对象。
问题在于您创建视图模型的方式。视图模型应该是自包含的,包括对其进行操作的功能。它应该是这样的:
var ViewModel = function() {
var self = this;
self.type = ko.observable();
self.name = ko.observable();
self.content = ko.observable();
self.type.subscribe(function(newVal) {
// here you have access to all the viewmodel properties through self
});
return self;
};
这是一个使用 var self=this;
pattern.To 的构造函数,使用您需要实例化它的视图模型,即 var vm = new ViewModel()
。 (可以省略new
)。
当然你也可以定义一个函数,绑定到self
,或者在构造函数中接收回调,绑定到self
。在这种情况下,函数实现将通过 this
访问视图模型,而不是 self,后者在函数体内是未定义的。
var doSomethignWithVm = function(newVal) {
// acces viewmodel via this
// you can also use newVal
};
您修改构造函数以将此作为回调接收:
var ViewModel = function(doSomethingCallback) {
self.type.subscribe(callback.bind(self));
};
这种模式没有多大意义,因为您的回调应该知道您的视图模型。在这种情况下,将订阅功能直接包含在模型中更有意义。
编辑 注意:正如我在对 Joel Ramos Michaliszen 的回答的评论中提到的,这两个代码是等效的:
self.type.subscribe(callback.bind(self));
self.type.subscribe(callback.bind, self);
您可以通过在文件 knockout/src/subscribales/subscribable.js
中查看 knockout's gitbhub 中 subscribable
的源代码来检查这一点。如果您寻找订阅实现,您会看到:
subscribe: function (callback, callbackTarget, event) {
// ...
boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
即如果您提供第二个参数,它用于将第一个参数中传递的函数绑定到它。
也许当你订阅一个 observable 时,你可以传递 2 个参数,第一个是 callback,第二个是scope/context,试试这样:
element.type.subscribe(this._typeChanged, element)
subscribe函数接受三个参数:callback是每当通知发生时调用的函数,target(可选)定义回调函数中this的值,event(可选;默认为"change") 是接收通知的事件的名称。
虽然我知道我可能采用了错误的方法,但我也处于无法对应用程序进行任何重大更改的阶段。
我发现我可以使用 lodash 来帮助我解决这个问题。 我最终使用部分函数将元素附加为订阅回调中的参数:
element.type.subscribe(_.partial(this.typeChanged, element))
或在 coffeescript 中
element.type.subscribe $_.partial @typeChanged, element
现在 chartTypeChanged 在输入上有 2 个参数,而不是一个。