1

我正在尝试从 Ember.js 控制器触发一个事件,以便监听视图可以自行更新。这是咖啡脚本。

window.CMS.EdmController = Ember.ObjectController.extend Ember.Evented,
  actions:
   save_edm: ->
     postData = $('#edm_form').serialize()
     $.ajax(
       url: 'cms2/update_edm',
       type: 'POST',
       data: postData
       )
       .done ->
         console.log(@)
         @trigger('saveEdmSuccessful')

它失败并出现错误 Object #Object has no method trigger。.done 函数中的 @ 指的是 jQuery post 对象而不是控制器。

如何从 jQuery 回调中获取对父控制器对象的引用?

任何指导将不胜感激。

4

1 回答 1

2

我确实尝试编译你的 Coffeescript 并最终得到以下代码作为输出:

window.CMS.EdmController = Ember.ObjectController.extend(Ember.Evented, {
  actions: {
    save_edm: function() {
      var postData;
      postData = $('#edm_form').serialize();
      return $.ajax({
        url: 'cms2/update_edm',
        type: 'POST',
        data: postData
      }).done(function() {
        console.log(this);
        return this.trigger('saveEdmSuccessful');
      });
    }
  }
});

您所面临问题的解决方案与 ember.js 无关,而与 Javascript 闭包的工作方式有关。解决上述问题的方法是:

window.CMS.EdmController = Ember.ObjectController.extend(Ember.Evented, {
  actions: {
    save_edm: function() {
      var postData;
      postData = $('#edm_form').serialize();
      return $.ajax({
        url: 'cms2/update_edm',
        type: 'POST',
        data: postData
      }).done($.proxy(function() {
        console.log(this);
        return this.trigger('saveEdmSuccessful');
      },this));
    }
  }
});

请注意我如何将您的.done处理程序从函数调用替换为代理调用。这确保在执行回调时,上下文会更新以反映当前的this.

要进一步了解thisJavaScript 中的行为,请阅读这篇文章

供您参考,这是我的解决方案的 CoffeeScript 等效项:

window.CMS.EdmController = Ember.ObjectController.extend Ember.Evented,
  actions:
   save_edm: ->
     postData = $('#edm_form').serialize()
     $.ajax(
       url: 'cms2/update_edm',
       type: 'POST',
       data: postData
       )
       .done(
          $.proxy ->
            console.log(@)
            @trigger('saveEdmSuccessful')
          @
       )
于 2014-03-16T08:37:14.740 回答