2015-07-11 5 views
5

Sto lavorando per convertire il mio semplice grafico ad albero di JavaScript in un jQuery Plugin.Aggiornare il plug-in jQuery per creare HTML e impedirne la ricostruzione su più chiamate

E 'il mio primo plugin jQuery e potrei usare un certo aiuto in un luogo paio prega ...

demo di quello che ho finora: http://jsfiddle.net/jasondavis/qsgqebox/

riportano di seguito le JavaScript che ho finora.

jQuery

jQuery.fn.updatePercentageGraph = function (options) { 

    var settings = $.extend({ 
      // These are the defaults. 
      percent: 0, 
     }, options);  

    var percent = settings.percent; 

    if(typeof percent === 'undefined') { 
     var percent = parseInt(this.data('percent')); 
    }else{ 
     if(percent === '') { 
      var percent = parseInt(this.data('percent')); 
     }else{ 
      var percent = parseInt(percent); 
      this.attr('data-percent', percent); 
     } 
    } 

    var deg = 360*percent/100; 
    if (percent > 50) { 
     this.addClass('gt-50'); 
    }else{ 
     this.removeClass('gt-50'); 
    } 
    $('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)'); 
    $('.ppc-percents span').html(percent+'%'); 

}; 

Usage:

$('#project_progress2').updatePercentageGraph(34); 

Che cosa ho bisogno di aiuto con:

1)
Attualmente richiedono all'utente di impostare il codice HTML in questo modo:

<div id="project_progress" class="progress-pie-chart" data-percent="40"> 
    <div class="ppc-progress"> 
     <div class="ppc-progress-fill4" style="transform: rotate(136.8deg);"></div> 
    </div> 
    <div class="ppc-percents4"> 
     <div class="pcc-percents-wrapper"> 
      <span>40%</span> 
     </div> 
    </div> 
</div> 

Quello che voglio fare è però farlo dove si può semplicemente fare qualcosa di simile ....

<div id="project_progress" class="progress-pie-chart" data-percent="40"></div> 

e il plugin jQuery crea automaticamente i nodi figlio appropriati.

La jQuery parte sarebbe auto create:

<div class="ppc-progress"> 
    <div class="ppc-progress-fill4" style="transform: rotate(136.8deg);"></div> 
</div> 
<div class="ppc-percents4"> 
    <div class="pcc-percents-wrapper"> 
     <span>40%</span> 
    </div> 
</div> 

2) aggiornare alcuni selettori per consentire a più grafici ad anello a pagina

Un altro problema nel plugin finora è il 3a e 4a riga dalla parte inferiore del codice JavaScript mostrato sopra. Si chiama $('.ppc-progress-fill') e $('.ppc-percents span') che impedirebbe l'utilizzo di più grafici sulla pagina, quindi è necessario aggiornarli per scegliere come target solo la classe presente nel grafico corrente.


3) Ottimizzare per evitare che la struttura HTML di essere ricreata ogni volta che la funzione viene chiamata per aggiornare il valore percentuale

Se converto questo plugin per auto-generare la struttura HTML, quindi devo anche considerare di ottimizzarlo in modo che non debba continuare a rigenerare la struttura più e più volte ogni volta che viene eseguito il codice che chiamerà $('#project_progress2').updatePercentageGraph(34); perché nel mio progetto dove userò questo, questi grafici saranno costantemente aggiorni lì valori percentuali.

Forse potrebbe anche essere meglio avere una funzione che crea l'HTML del grafico iniziale e quindi una seconda funzione che può essere chiamata ripetutamente e ripetutamente che gestisce solo l'aggiornamento della percentuale e non tenterà di ricostruire e iniettare la struttura HTML più e più volte!


Questi problema che ho citato sono le aree chiave sono un po 'bloccato in questo momento e potrebbe usare un certo aiuto per favore.

JSFiddle Demo:

JSFiddle di quello che ho finora insieme ad alcuni pulsanti per testare l'aggiornamento dei valori percentuali: http://jsfiddle.net/jasondavis/qsgqebox/

+0

Hai provato a creare un plugin jQuery di base prima? Una buona guida di partenza è questa, prima di provare molto altro: http://www.smashingmagazine.com/2011/10/11/essential-jquery-plugin-patterns/ – MyStream

+0

@MyStream Domanda riscritta con i miei tentativi e cosa sono alle prese con – JasonDavis

+0

Quando si crea la funzione, stabilire cosa è "questo".Se la lunghezza è> 1, probabilmente vuoi associare a ciascun oggetto a turno e prendere $ (questo) o equivalente su cui agire quando chiami la funzione, che ti aiuterà a mantenere l'ambito di qualsiasi chiamata di metodo relativa all'oggetto su quale sei azione. – MyStream

risposta

2

1) La parte jQuery sarebbe automaticamente creare

Per risolvere questo punto è necessario creare la struttura HTML sulla creazione di plugin.

2) aggiornare alcuni selettori per consentire a più grafici ad anello a pagina

Prevenire utilizzando i selettori pagina intera. Invece, puoi mantenere un riferimento alla struttura HTML creata e lavorare solo su questo sottoinsieme. Non l'intero DOM.

3) Ottimizza per evitare che la struttura HTML venga ricreata ogni volta che la funzione viene chiamata per aggiornare il valore percentuale

Un modello usuale per risolvere più istanze è quello di creare un attributo data che contiene l'istanza del plugin. Se un'istanza esiste già, devi solo agire su quell'istanza invece di crearne una nuova.

Questa istanza è utile anche per un altro modello jQuery per l'aggiunta di metodi ai plugin. Puoi verificare se il parametro passato al plugin è una stringa e quindi chiamare un metodo con quel nome.

$('#project_progress').updatePercentageGraph('percent', percent); 

Inoltre è possibile ottenere il valore utilizzando lo stesso metodo senza parametri:

var percent = $('#project_progress').updatePercentageGraph('percent'); 

Tutto in uno, vorrei suggerire qualcosa di simile:

(function ($, undefined) { 
    'use strict'; 
    function PercentageGraph(element, options) { 
     this.$percentageGraph = $(element).append(
      '<div class="ppc-progress">' + 
       '<div class="ppc-progress-fill"></div>' + 
      '</div>' + 
      '<div class="ppc-percents">' + 
       '<div class="pcc-percents-wrapper">' + 
        '<span>0%</span>' + 
       '</div>' + 
      '</div>' 
     ); 
     this.options = $.extend({}, $(element).data(), options); 
     this._init(); 
    } 
    PercentageGraph.prototype = { 
     _init: function() { 
      this.percent(this.options.percent || 0); 
     }, 
     _update: function() { 
      var percent = this.options.percent; 
      var deg = 360*percent/100; 
      if (percent > 50) { 
       this.$percentageGraph.addClass('gt-50'); 
      }else{ 
       this.$percentageGraph.removeClass('gt-50'); 
      } 
      this.$percentageGraph.find('.ppc-progress-fill').css('transform','rotate('+ deg +'deg)'); 
      this.$percentageGraph.find('.ppc-percents span').html(percent+'%'); 
     }, 
     percent: function (percent) { 
      // If no parameter, act as a getter. Otherwise act as a setter. 
      if (percent === undefined) { 
       return this.options.percent; 
      } else { 
       this.options.percent = percent; 
       this._update(); 
      } 
     }, 
    } 

    $.fn.updatePercentageGraph = function (options) { 
     var args = Array.prototype.slice.call(arguments, 1), 
      result; 
     this.each(function() { 
      var plugin = $(this).data('percentage-graph'); 
      if (!plugin) { 
       $(this).data('percentage-graph', (plugin = new PercentageGraph(this, options))); 
      } 
      var method = typeof options === 'string' ? options : '_init'; 
      result = plugin[method].apply(plugin, args); 
      // Break the .each iteration if it is a getter, that is, when the method returns something. 
      return result === undefined; 
     }); 
     return result || this; 
    }; 
}(jQuery)); 

Vedi demo

+0

Ho finalmente avuto il tempo di guardare questo ... questo è fantastico! Sono molto felice grazie per aver trovato il tempo per farlo. Avevo iniziato la mia versione che non era nemmeno simile alla tua versione. Il mio ha quasi funzionato, ma le tue versioni sono strutturate proprio come immagino dovrebbe essere! C'è un piccolo problema che ho notato finora. Quando aggiorni la percentuale con il pulsante sulla demo che hai collegato, non aggiorna il valore dell'attributo dati DOM 'data-percent =" 20 "' quindi il numero per questo rimane lo stesso dopo aver fatto gli aggiornamenti ..... (continua di spazio ...) – JasonDavis

+0

.... (cont.) ... L'apparenza saggia non influisce su nulla, tuttavia nella mia app dal vivo ho bisogno di accedere a quel valore di dati in modo che è per questo che ho impostato. Cercherò di aggiornarlo ma se fallisco, posterò di nuovo qui per vedere se potresti essere in grado di dare una mano. Apprezzo molto quello che hai fatto, è molto pulito e mi ha insegnato un nuovo modo per strutturare un plugin jQuery e avere più di una funzione nel plugin. I documenti jQuery mostrano un modo completamente diverso che è IMO sciatto! – JasonDavis

+0

Sto solo leggendo la tua risposta ... sono entusiasta del codice prima! 'Un normale schema per risolvere istanze multiple è creare un attributo di dati che contenga l'istanza del plugin. ' Lo vedo spesso così grazie per aver spiegato lo scopo! – JasonDavis

2

Sono pazzo? Sì, lo sono!

Qui sono http://jsfiddle.net/qsgqebox/3/

Non ho intenzione di spiegare a tutti voi questo codice. Voglio solo dire che questo è il modo in cui solitamente codifico i plugin per jQuery.

(function($) { 
    'use strict'; 

    var PercentageGraph = function(element) { 
     // Setup settings 
     this.settings = $.extend({ 
      percent: element.data('percent') ? element.data('percent') : 0 
     }); 

     // Store the given element 
     this.element = element; 

     // Create the progress bar 
     this.create(); 

     // Initialization 
     this.update(); 
    } 

    PercentageGraph.prototype = { 
     create: function() { 
      // Create: 
      // <div class="ppc-progress"> 
      //  <div class="ppc-progress-fill4"></div> 
      // </div> 
      this.progress = $('<div />'); 
      this.progress.addClass('ppc-progress'); 

      this.progressFill = $('<div />'); 
      this.progressFill 
       .addClass('ppc-progress-fill') 
       .appendTo(this.progress); 

      // Create: 
      // <div class="ppc-percents4"> 
      // <div class="pcc-percents-wrapper"> 
      //  <span>40%</span> 
      // </div> 
      // </div> 
      this.percents = $('<div />'); 
      this.percents.addClass('ppc-percents'); 

      this.percentsWrapper = $('<div />'); 
      this.percentsWrapper 
       .addClass('pcc-percents-wrapper') 
       .appendTo(this.percents); 

      this.percentsContent = $('<span />'); 
      this.percentsContent 
       .text(this.settings.percent) 
       .appendTo(this.percentsWrapper); 

      // Append everything to the element 
      this.progress.appendTo(this.element); 
      this.percents.appendTo(this.element); 
     }, 
     update: function(p) { 
      var percent = p ? p : this.settings.percent, 
       deg = 360 * percent/100; 

      if (percent > 50) { 
       this.element.addClass('gt-50'); 
      } else { 
       this.element.removeClass('gt-50'); 
      } 

      this.progressFill.css('transform', 'rotate('+ deg +'deg)'); 
      this.percentsContent.html(percent + '%'); 
     } 
    } 

    jQuery.fn.percentageGraph = function() { 
     return new PercentageGraph(this); 
    } 
})(jQuery); 

(function($) { 
    $(document).ready(function() { 
     var progress = $('div#project_progress').percentageGraph(); 

     // Handle it 
     $('.update-button').on('click', function() { 
      var percent = $(this).data('percent'); 

      // Update it 
      progress.update(percent); 
     });   
    }); 
})(jQuery); 
+0

L'ho giocato da solo e ho lavorato molto, ma mi piace molto il modo in cui lo hai strutturato molto meglio! La mia versione era basata sulle demo del sito di documenti jQuery, quindi è bello vedere strutture alternative come questa. Grazie per la condivisione, lo verificherò ora e poi commenterò! – JasonDavis

Problemi correlati