【问题标题】:Function _.bind() won't bind an object函数 _.bind() 不会绑定对象
【发布时间】:2017-01-09 22:28:07
【问题描述】:

我有一个扩展 SugarCRM CreateView 的视图类,当字段 starting_months_c 更改时,我希望 this 在函数 checkMonths 中成为 this.model,因此我可以键入 this.get() 而不是 this.model.get() .

/**
 * @class View.Views.Base.DoVPCreateView
 * @alias SUGAR.App.view.views.DoVPCreateView
 * @extends View.Views.Base.CreateView
 */
({
    extendsFrom: 'CreateView',
    initialize: function(options) {
        this._super('initialize', arguments);
        // ....
        this.model.on('change:starting_month_c', _.bind(this.checkMonths, this.model));
        // ....
    },
    checkMonths: function() {
        if (this.get('starting_month') == 12) {
            // ....
        }
    }

不幸的是,这个结构不起作用。我想知道,也许是因为.on() 函数以某种方式设置了上下文本身?

我在文档中发现,您可以将上下文作为第三个参数传递给函数

object.on(event, callback, [context])

我试过了,但结果还是一样 - 视图是 this,而不是 model

【问题讨论】:

    标签: javascript events backbone.js underscore.js sugarcrm


    【解决方案1】:

    快速修复

    将上下文直接提供给.on

    this.model.on('change:starting_month_c', this.checkMonths, this.model);
    

    但这样做只是一种误导性的修复。视图的函数都应该有 this 作为视图实例,而不是其他任意对象。

    // a simple example view
    var View = Backbone.View.extend({
      initialize: function() {
        console.log("View init, month:", this.model.get('month'));
        
        // bind the context
        this.model.listenTo(this.model, "change:month", this.checkMonth);
      },
      // the callback
      checkMonth: function() {
        // here, `this` is the model which you should NOT do.
        // but for demonstration purpose, you can use `this.get` directly.
        console.log("checkMonth:", this.get('month'));
      },
    });
    
    // sample for the demo
    var model = new Backbone.Model({
        month: 2 // dummy value
      }),
      view = new View({
        model: model
      });
    
    console.log("change month");
    model.set({
      month: 3 // set to trigger the callback
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

    真正的修复

    如果您总是想在 starting_month_c 在此模型的任何实例中发生更改时触发检查“月”回调,您可以将其移至模型类本身。

    var Model = Backbone.Model.extend({
        initialize: function() {
            // favor listenTo over `on` or `bind`
            this.listenTo(this, 'change:starting_month_c', this.checkMonths);
        },
        checkMonths: function(model, value, options) {
            if (this.get('starting_month') === 12) {
                // whatever you want
            }
        }
    });
    

    如果只针对这个特定的视图,在回调中使用this.model.get,因为它应该是。这不是问题,这是标准的做法。

    更多关于为什么favor listenTo的信息。

    【讨论】:

    • 重点是,我只想在创建模型时进行一些验证。但是你是正确的 - 没有这个,因为类函数中的类有点乱,我现在可以看到它......我通常会使用 this.model.get() :) 但是(现在纯粹出于教育目的)我在我的编辑中写道,我试图将模型作为上下文传递,结果仍然没有出现
    • @Charlestone 作为一个教育示例,我添加了一个堆栈 sn-p 来证明它按预期工作。因此,如果它在您这边不起作用,那么其他东西正在以某种方式手动更改预绑定每个实例函数的上下文。
    【解决方案2】:
    猜你喜欢
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 2013-01-26
    • 1970-01-01
    相关资源
    最近更新 更多