javascript - 函数 _.bind() 不会绑定(bind)对象

标签 javascript events backbone.js underscore.js sugarcrm

我有一个扩展 SugarCRM CreateView 的 View 类,我希望 this 成为函数 checkMonths 中的 this.model > 当字段 starting_months_c 更改时,我可以键入 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])

我试过了,但结果还是一样—— View 是this,而不是model

最佳答案

快速修复

直接给.on上下文:

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

但这样做只是误导性的修复。 View 的函数都应将 this 作为 View 实例而不是其他任意对象。

// 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
        }
    }
});

如果仅针对此特定 View ,应在回调中使用 this.model.get。这不是问题,这是执行此操作的标准方法。

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

关于javascript - 函数 _.bind() 不会绑定(bind)对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41558033/

相关文章:

jquery - 我可以在 CKEDITOR 中的元素上添加 onclick 事件吗?

ruby-on-rails - 在服务器(Node.js 和 Rails)和客户端上运行 Backbone 进行复杂验证是否明智?

Javascript:覆盖 Backbone 模型的原型(prototype)

javascript - 从表单检索数据(Codeigniter、AJAX)

javascript - 带有 webpack 和 Reactjs 的 django runserver 项目结构

javascript - onchange 事件不会在 MSIE 中冒泡。我在哪里可以找到列出所有此类事件的图表

javascript - 如何在所有ajax调用中向URL添加参数?

javascript - 需要与 EXT JS 工具提示功能相关的帮助

javascript - Geddy 应用程序中的脚本 src 属性出现问题

python - 按 T​​ab 或 Enter 键时获取 QTableView 单元格值