0

我试图通过保持我使用的各种功能简短且相对容易测试来保持我正在开发的 jquery 插件的可配置性和可维护性。

为此,我使用了一些 jQuery 插件代码,基于jQuery 样板Addy Osmani 的 Lightweight Start,有一个插件,我可以在其中传递覆盖,并从一系列小函数中组合现有函数。

但是,我在弄清楚如何访问我在延迟done()回调中声明的函数时遇到了一些麻烦,而无需done()再次在函数调用中声明所有函数代码。

当使用样板中概述的基于原型的方法时,是否有推荐的模式来使这些功能可用?

(function($, window, document, undefined) {

  var pluginName = 'myModule';

  function myModule(element, options) {
    this.element = element;

    //  allow override of defaults
    this.options = $.extend({}, defaults, options);

    this._defaults = defaults;
    this._name = pluginName;

    // calling the init() function defined below
    this.init();
  }

  myModule.prototype = {

    init: function() {
      // add listeners for clicks on the element, and trigger some 
      // behaviour defined in fetchScore()
      $(this.element).click(function() {
        that.fetchScore();
        return false;
      });

    },
    handySuccessFunction: function() {
      // some handy DOM manipulation stuff,
      // kept out the main fetchScore function,
      // ideally to make it more testable and readable
    },
    handyFailingFunction: function() {
      // same again for failing case
    },

    fetchScore: function(authToken) {

      $.getJSON(this.options.endpoint, {
        apiKey: this.options.apiKey,
        otherParam: this.options.otherParam,
        token: authToken
      })
        .done(function(json) {
        // I want to call the handySuccessFunction() here,
        // but I have no access to myModule
      })
        .fail(function(jqxhr, textStatus, error) {
        // Likewise I want to call the handyFailingFunction() here
      });
    }
  }

  // A really lightweight plugin wrapper around the constructor,
  // preventing against multiple instantiations. 
  // We store a reference to the 
  $.fn[pluginName] = function(options) {
    return this.each(function() {
      if (!$.data(this, "plugin_" + pluginName)) {
        $.data(this, "plugin_" + pluginName,
          new pluginName(this, options));
      }
    });
  }

})(jQuery, window, document);

这是我的预期用法:

jQuery(document).ready(function($) {
  // console.log('clicking the popup');

  $('#elementToAttachTo').myModule();

  // clicking on this to trigger the fetchScore
  // behaviour in myModule
  $('#elementToAttachTo').click();

})
4

1 回答 1

0

您应该在“done”中使用“bind”来回调函数,将其上下文(“this”)设置为 myModule 实例,其中声明了此函数。

有几种方法。

  1. 您可以使用适用于现代浏览器的 navtive Function.prototype.bind() 方法

  2. 您可以使用 jQuery $.proxy 函数。

所以

 myModule.prototype.fetchScore = function(authToken) {
    $.getJSON(this.options.endpoint, {
      apiKey: this.options.apiKey,
      otherParam: this.options.otherParam,
      token: authToken
    })
    .done(function(json) {
        this.handySuccessFunction();
    }.bind(this))
    .fail($.proxy(function(json) {
        this.handyFailingFunction();
    }, this))
    ;        
 };
于 2013-05-30T15:22:17.300 回答