Как иметь членские переменные и открытые методы в плагине jQuery?

Большинство компиляторов C обеспечивает -o опция для этого, такая как:

gcc -o gentext gentext.c
cc  -o mainprog -Llib -lmymath firstbit.c secondbit.o
xlc -o coredump coredump.c
5
задан Mogsdad 28 February 2018 в 02:05
поделиться

6 ответов

Я обнаружил, что способ обработки этого пользовательского интерфейса jQuery, кажется, работает лучше всего. Вы создаете свои «дополнительные методы» в качестве строкового аргумента вашего плагина:

$('#elem').autoCompleteEx('addItem', '1');

Затем контекст «this» сохраняется, и вы можете делать что-то в этом направлении:

function addItem() {
  // this should be == jquery object when this get called
}

$.fn.autoCompleteEx = function(options) {
   if (options === 'addItem') {
     return addItem.apply(this, Array.prototype.splice.call(arguments, 1));
   }
};
7
ответ дан 18 December 2019 в 13:16
поделиться

Вот шаблон, с которым я экспериментирую при создании более сложных плагинов виджетов:

(function($){

  // configuration, private helper functions and variables
  var _defaultConfig = {
        /* ... config ... */
      },
      _version = 1;


  // the main controller constructor
  $.myplugin = function ( elm, config ) {

    // if this contructor wasn't newed, then new it...
    if ( this === window ) { return new $.myplugin( elm, config || {} ); }

    // store the basics
    this.item = $( elm );
    this.config = new $.myplugin.config( config );

    // don't rerun the plugin if it is already present
    if ( this.item.data( 'myplugin' ) ) { return; }

    // register this controlset with the element
    this.item.data( 'myplugin', this );

    // ... more init ...

  };
  $.myplugin.version = _version;
  $.myplugin.config = function ( c ) { $.extend( this, $.myplugin.config, c ); };
  $.myplugin.config.prototype = _defaultConfig;
  $.myplugin.prototype = {

    /* ... "public" methods ... */

  };

  // expose as a selector plugin
  $.fn.myplugin = function ( config ) {
    return this.each(function(){
      new $.myplugin( this, config );
    });
  };

})(jQuery);

Я помещаю конфигурацию и версию по умолчанию наверху просто потому, что это наиболее вероятно то, что ищет любой читающий код. В большинстве случаев вы просто хотите исследовать блок настроек.

Это откроет "myplugin" в двух местах в качестве конструктора для "контроллера" виджета. на $ и как метод сбора на $ .fn . Как вы можете видеть, метод $. Fn на самом деле ничего не делает, кроме создания экземпляров новых контроллеров.

Конфигурация - это унаследованный от прототипа объект, где по умолчанию используется прототип. Это дает расширенную гибкость с начальными значениями, поскольку вы можете назначьте "следующие" значения по умолчанию в $. myplugin.config или измените значение по умолчанию для каждого запущенного плагина с помощью $. myplugin.config.prototype . Это требует от вас всегда назначайте их с помощью $ .extend, иначе вы сломаете систему. Этому может противостоять дополнительный код, но я предпочитаю знать, что делаю. : -)

Экземпляр контроллера привязывается к элементу через метод jQuery data () и фактически использует его для проверки того, что он не запускается дважды для одного и того же элемента (хотя вы можете разрешить его перенастройку).

Это дает вам следующий интерфейс к контроллеру:

// init:
$( 'div#myid' ).myplugin();

// call extraMethod on the controller:
$( 'div#myid' ).data('myplugin').extraMethod();

Самым большим недостатком этого подхода является то, что поддерживать контекст «this» при каждом событии немного затруднительно. назначение. Пока контекст для событий не поступит в jQuery, это нужно делать с большим количеством закрытий.

Вот приблизительный пример того, как может выглядеть (неполный и бесполезный) плагин:

(function($){

  // configuration, private helper functions and variables
  var _defaultConfig = {
        openOnHover: true,
        closeButton: '<a href="#">Close</a>',
        popup: '<div class="wrapper"></div>'
      },
      _version = 1;

  // the main controller constructor
  $.myplugin = function ( elm, config ) {

    // if this contructor wasn't newed, then new it...
    if ( this === window ) { return new $.myplugin( elm, config || {} ); }
    this.item = $( elm );
    this.config = new $.myplugin.config( config );
    if ( this.item.data( 'myplugin' ) ) { return; }
    this.item.data( 'myplugin', this );

    // register some events
    var ev = 'click' + ( this.config.openOnHover ) ? ' hover' : '';
    this.item.bind(ev, function (e) {
      $( this ).data( 'myplugin' ).openPopup();
    });

  };
  $.myplugin.version = _version;
  $.myplugin.config = function ( c ) { $.extend( this, $.myplugin.config, c ); };
  $.myplugin.config.prototype = _defaultConfig;
  $.myplugin.prototype = {

    openPopup: function () {
      var C = this.config;
      this.pop = $( C.popup ).insertAfter( this.item );
      this.pop.text( 'This says nothing' );
      var self = this;
      $( C.closeButton )
          .appendTo( pop )
          .bind('click', function () {
            self.closePopup();  // closure keeps context
            return false;
          });
      return this;  // chaining
    },

    closePopup: function () {
      this.pop.remove();
      this.pop = null;
      return this;  // chaining
    }

  };

  // expose as a selector plugin
  $.fn.myplugin = function ( config ) {
    return this.each(function(){
      new $.myplugin( this, config );
    });
  };

})(jQuery);
4
ответ дан 18 December 2019 в 13:16
поделиться

Обратите внимание на функциональность jQuery .data . Он позволяет хранить пары ключ / значение для любого объекта.

1
ответ дан 18 December 2019 в 13:16
поделиться

Используйте что-то вроде этого:

acx.data("acx-somename", datavalue);

Затем вы можете позже получить его с помощью:

var datavalue = acx.data("acx-somename");
1
ответ дан 18 December 2019 в 13:16
поделиться

Манипуляция экземпляром! Это то, что вы хотите, верно? Старая добрая мода, манипуляции с экземплярами в реальном времени. Я тоже этого хотел. Я погуглил тот же вопрос и нигде не смог получить хорошего ответа (как и те, что указаны выше), поэтому я понял это. Мне не нравится мое решение, потому что оно кажется обходным способом получить доступ к методам экземпляра и странным для потребителя jquery, но jQuery в первую очередь чертовски странный, но прекрасный. Я написал простой плагин для затухания изображений, но затем, когда мне нужно было сделать с ним больше, я захотел предоставить методы для живого экземпляра, чтобы получить этот результат здесь -> пример , я сделал следующее:

var instanceAccessor = {};
var pluginOptions = {'accessor':instanceAccessor}
$('div').myPlugin(pluginOptions);

Затем внутри плагина я добавляю методы к этому переданному объекту 'accessor', поскольку это объект. Я предоставляю методы внутри плагина следующим образом:

if (pluginOptions.accessor != null && typeof(pluginOptions.accessor) === 'object') {
   pluginOptions.accessor.exposedMethod = function (someParam) {
     // call some private function here and access private data here
   };
}

Затем,

0
ответ дан 18 December 2019 в 13:16
поделиться

Вот мой взгляд на это:

У меня есть объект в замыкании, который используется для создания экземпляров объектов. Объекты экземпляра прикрепляются к узлу элемента с помощью метода jQuery data (). У этих экземпляров есть общедоступные методы, которые вы можете вызывать по мере необходимости.

(function($)
{     
// This is used to create AutoComplete object that are attatched to each element that is matched
// when the plugin is invoked
var AutoCompleteEx = function(options, acx) {

  // PRIVATE VARIABLES
  var timerID;
  var input;

  //Give Div Correct Class & Add <ul> w/ input item to it
  acx.addClass("autoCompleteEx"); 
  acx.html("<ul><li class=\"input\"><input type=\"text\"/></li></ul>");

  //Grab Input As JQ Object
  input = $("input", acx);

  //Wireup Div
  acx.click(function()
  {
      input.focus().val( input.val() );
  });


  //Wireup Input
  input.keydown(function(e)
  {
      var kc = e.keyCode;
      if(kc == 13)   //Enter
      {

      }
      else if(kc == 27)  //Esc
      {

      }
      else
      {
          //Resize TextArea To Input
          var width = 50 + (_txtArea.val().length*10);
          _txtArea.css("width", width+"px");    
      }
  });

  // PUBLIC METHODS

  this.setTimerID = function(id) {
    timerID = id;
  };

  this.getTimerID = function() {
    return timerID;
  };

};


//Attach this new method to jQuery   
$.fn.autoCompleteEx = function(options)
{    
    //Merge Given Options W/ Defaults, But Don't Alter Either
    var opts = $.extend({}, $.fn.autoCompleteEx.defaults, options);

    //Iterate over the current set of matched elements   
    return this.each(function() 
    {
        var acx = $(this); //Get JQuery Version Of Element (Should Be Div)

        // creating a new AutoCompleteEx object and attach to the element's data, if not already attached
        if (!acx.data('autoCompleteEx')) {
          acx.data('autoCompleteEx', new AutoCompleteEx(options, acx));
        }

    });   //End Each JQ Element

}; //End autoCompleteEx()

//Default Settings
$.fn.autoCompleteEx.defaults =
{
    minChars:  2,
    delay:     300,
    maxItems:  1
};

//End Of Closure
})(jQuery);

Вы можете вызывать методы следующим образом:

$("div#someDiv").autoCompleteEx();
$("div#someDiv").data('autoCompleteEx').setTimerID(123);
var timerId = $("div").data('autoCompleteEx').getTimerID();
console.log(timerId); // outputs '123'

А если вы создаете более одного экземпляра:

$("div.someDiv").autoCompleteEx();
$("div.someDiv").eq(0).data('autoCompleteEx').setTimerID(123);
$("div.someDiv").eq(1).data('autoCompleteEx').setTimerID(124);
var firstTimerId = $("div").eq(0).data('autoCompleteEx').getTimerID();
var secondTimerId = $("div").eq(1).data('autoCompleteEx').getTimerID();
console.log(firstTimerId); // outputs '123'
console.log(secondTimerId); // outputs '124'
1
ответ дан 18 December 2019 в 13:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: