2013-03-21 20 views
12

Chcę utworzyć wtyczkę jQuery z konfiguracją (na przykład wtyczka myplugin). Następnie wywołanie $(elem).myplugin(config); Po tym chcę wywołać metody z tej wtyczki jak $(elem).myplugin().method() z już zapisanej konfiguracji.Czy dobrą praktyką jest przechowywanie konfiguracji wtyczki jquery w danych?

Moja oferta jest coś takiego:

(function($) { 
    $.fn.myplugin = function(options) { 
     var $this = $(this); 

     var getOptions = function() { 
      return $this.data('myplugin'); 
     }; 

     var initOptions = function(opt) { 
      $this.data('myplugin', opt); 
     }; 

     var setOption = function(key, value) { 
      $this.data('myplugin')[key] = value; 
     } 

     var updateBorderWidth = function() { 
      $this.css('border-width', 
         getOptions().borderWidth * getOptions().coeficient); 
     }; 

     var init = function(opt) { 
      initOptions(opt); 
      updateBorderWidth(); 
     }   

     function changeBorder(width) {    
      setOption('borderWidth', width) 
      updateBorderWidth(); 
     } 

     if(options) { 
      init(options);    
     }   

     return { 
      changeBorder : changeBorder 
     }; 
    }   
})(jQuery); 

i użytkowania:

$(function() { 
    var item1 = $('#test1').myplugin({ coeficient: 1, borderWidth: 1 }); 
    var item1 = $('#test2').myplugin({ coeficient: 2, borderWidth: 1 }); 

    $('#btn').click(updateBorder);  
}); 

function updateBorder() { 
    $('#test1').myplugin().changeBorder($('#inpt').val()); 
    $('#test2').myplugin().changeBorder($('#inpt').val()); 
} 

Przykład: http://jsfiddle.net/inser/zQumX/4/

Moje pytanie: czy jest to dobra praktyka, aby to zrobić?

Może to niewłaściwe podejście. Czy możesz zaoferować lepsze rozwiązanie?

+0

Świetne rozwiązanie! – whatswrong

Odpowiedz

2

Edit:

Po wyszukaniu wątków na jQuery plugin template znalazłem te Boilerplate templates które są bardziej wszechstronne i bogate wzory niż co ja oferowane poniżej. Ostatecznie to, co wybierzesz, zależy od Twoich potrzeb. Szablony Boilerplate obejmują więcej przypadków użycia niż moja oferta, ale każda z nich ma swoje zalety i zastrzeżenia w zależności od wymagań.


Zazwyczaj jQuery wtyczki bądź wrócić obiektu jQuery gdy wartość jest przekazywana do nich na przykład:

.wrap(html) // returns a jQuery object 

albo zwraca wartość, gdy parametr nie jest przekazywana

.width() // returns a value 

.height() // also returns a value 

Aby przeczytać przykładową konwencję telefoniczną:

$('#test1').myplugin().changeBorder($('#inpt').val());

wydaje się, aby każdego dewelopera, który używa jQuery, jakby dwa oddzielne wtyczki są wykorzystywane w tandemie, pierwszy .myplugin() który by przyjąć zwróci obiekt jQuery z pewnym maniplulation domyślny DOM wykonywanej na #test1, a następnie .changeBorder($('#inpt').val()), który może również zwrócić obiekt jQuery, ale w przypadku twojego przykładu cała linia nie jest przypisana do zmiennej, więc żadna wartość zwracana nie jest używana - znowu wygląda jak manipulacja DOM. Ale twój projekt nie jest zgodny ze standardową konwencją wywoływania, którą opisałem, więc może być trochę zamieszania dla każdego, kto patrzy na twój kod, co to naprawdę robi, jeśli nie są zaznajomieni z twoją wtyczką.


mam w przeszłości, uważany za podobny problem i korzystać sprawę, którą opisujesz i podoba mi się pomysł posiadania dogodnym konwencję za nazwanie oddzielne funkcje związane z wtyczki. Wybór należy wyłącznie do ciebie - to twoja wtyczka i będziesz musiał zdecydować na podstawie tego, kto będzie z niej korzystał, ale sposób, w jaki się zdecydowałem, to po prostu przekazać nazwę funkcji i jej parametrów albo jako oddzielną .myplugin(name, parameters) lub w obiekcie jako .myplugin(object).

I zazwyczaj to zrobić tak:

(function($) { 
    $.fn.myplugin = function(fn, o) { // both fn and o are [optional] 
     return this.each(function(){ // each() allows you to keep internal data separate for each DOM object that's being manipulated in case the jQuery object (from the original selector that generated this jQuery) is being referenced for later use 
      var $this = $(this); // in case $this is referenced in the short cuts 

      // short cut methods 
      if(fn==="method1") { 
       if ($this.data("method1")) // if not initialized method invocation fails 
        $this.data("method1")() // the() invokes the method passing user options 
      } else if(fn==="method2") { 
       if ($this.data("method2")) 
        $this.data("method2")() 
      } else if(fn==="method3") { 
       if ($this.data("method3")) 
        $this.data("method3")(o) // passing the user options to the method 
      } else if(fn==="destroy") { 
       if ($this.data("destroy")) 
        $this.data("destroy")() 
      } 
      // continue with initial configuration 

      var _data1, 
       _data2, 
       _default = { // contains all default parameters for any functions that may be called 
        param1: "value #1", 
        param2: "value #2", 
       }, 
       _options = { 
        param1: (o===undefined) ? _default.param1 : (o.param1===undefined) ? _default.param1 : o.param1, 
        param2: (o===undefined) ? _default.param2 : (o.param2===undefined) ? _default.param2 : o.param2, 

       } 
       method1 = function(){ 
        // do something that requires no parameters 
        return; 
       }, 
       method2 = function(){ 
        // do some other thing that requires no parameters 
        return; 
       }, 
       method3 = function(){ 
        // does something with param1 
        // _options can be reset from the user options parameter - (o) - from within any of these methods as is done above 
        return; 
       }, 
       initialize = function(){ 
        // may or may not use data1, data2, param1 and param2 
        $this 
         .data("method1", method1) 
         .data("method2", method2) 
         .data("method3", method3) 
         .data("destroy", destroy); 
       }, 
       destroy = function(){ 
        // be sure to unbind any events that were bound in initialize(), then: 
        $this 
         .removeData("method1", method1) 
         .removeData("method2", method2) 
         .removeData("method3", method3) 
         .removeData("destroy", destroy); 
       } 
      initialize(); 
     }) // end of each() 
    } // end of function   
})(jQuery); 

A Zastosowanie:

var $test = $('#test').myplugin(false, {param1: 'first value', param2: 'second value'}); // initializes the object 
$test.myplugin('method3', {param1: 'some new value', param2: 'second new value'}); // change some values (method invocation with params) 

lub można po prostu powiedzieć:

$('#test').myplugin(); // assume defaults and initialize the selector 
2

Przekazywanie parametrów do javascript za pomocą atrybutów danych jest świetnym wzorcem, ponieważ skutecznie oddziela kod JavaScript i kod po stronie serwera. Nie ma to również negatywnego wpływu na testowalność kodu Javascript, który jest efektem ubocznym wielu innych podejść do problemu.

Posunąłbym się do stwierdzenia, że ​​jest to najlepszy sposób na komunikację kodu po stronie serwera z kodem po stronie klienta w aplikacji internetowej.

Powiązane problemy