【问题标题】:Knockout subscribe scope淘汰赛订阅范围
【发布时间】:2016-02-29 20:19:00
【问题描述】:

Knockout 中是否可以更改订阅范围?

我有这样的事情:

element =
    {
        type: ko.observable()
        name: ko.observable()
        content: ko.observable()
    }

element.type.subscribe(this._typeChanged.bind(element))

基本上我想访问我订阅的属性的对象。像我的代码一样绑定不起作用,因为它绑定到整个 VeiwModel 而不是对象。

【问题讨论】:

    标签: javascript knockout.js binding observable subscribe


    【解决方案1】:

    问题在于您创建视图模型的方式。视图模型应该是自包含的,包括对其进行操作的函数。应该是这样的:

    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; 模式的构造函数。要使用视图模型,您需要实例化它,即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;
    

    即如果您提供第二个参数,则它用于将第一个参数中传递的函数绑定到它。

    【讨论】:

      【解决方案2】:

      也许当你订阅一个 observable 时你可以传递 2 个参数的淘汰句柄,第一个是 callback,第二个是 scope/上下文,试试这样的:

      element.type.subscribe(this._typeChanged, element)

      subscribe 函数接受三个参数:callback 是通知发生时调用的函数,target(可选)定义回调函数中 this 的值,以及 event(可选;默认为“change”)是要接收通知的事件的名称。

      参考。 http://knockoutjs.com/documentation/observables.html

      【讨论】:

      • 我什至不知道这一点,这是一个很好的例子,说明如何用心阅读文档可以获得更好的结果!现在,如果您可以提供一个带有此参数的订阅调用的简单示例,那就完美了。
      • @Tyblitz 此代码与 OP 问题代码完全相同。如果你在github.com/knockout 中检查subscribable 的实现,在文件knockout/src/subscribales/subscribable.js 中,你会看到:subscribe: function (callback, callbackTarget, event) { 和里面var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback; 即。如果您提供第二个参数,则函数将绑定到它。所以这个答案没有什么不同。我故意将.bind() 包含在我的答案中,因为它与OP 问题有关。
      【解决方案3】:

      虽然我知道我可能有错误的方法,但我也处于无法对应用程序进行任何重大更改的阶段。

      我发现我可以使用 lodash 来帮助我解决这个问题。 我最终使用部分函数将元素作为参数附加到订阅回调中:

      element.type.subscribe(_.partial(this.typeChanged, element))
      

      或在咖啡脚本中

      element.type.subscribe $_.partial @typeChanged, element
      

      现在 chartTypeChanged 在输入上有 2 个参数而不是一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-20
        • 2015-01-04
        • 2012-10-09
        • 2015-03-27
        • 1970-01-01
        • 2012-05-26
        • 2016-06-09
        • 1970-01-01
        相关资源
        最近更新 更多