2016-02-01 16 views
10

Vorrei chiedere aiuto perché non riesco a convertire il mio classico jQuery (v2) in ES6 con modulo e classe.Estendi plug-in ES6 a jQuery prototype

In ECMAScript 5, siamo in grado di collegare plugin jQuery in jQuery prototipo in questo modo:

app.js - jQuery caricato tramite HTML <script> tag

$.fn.myPlugin = function() {}; 
$('div').myPlugin(); 

E funziona :). In ES6, vorrei scrivere qualcosa di simile:

myPlugin.es6:

import $ from 'jquery'; 

export default class myPlugin extends $ { 
// Could i use constructor() method ??? 
} 

app.es6:

import $ from 'jquery'; 
import myPlugin from 'myPlugin.es6'; 

$('div').myPlugin(); 

E, infine, non funziona ...
Ho cercato e nessuno mi ha mai fatto questa domanda.
Io uso Babel per traspolare ES6 in ES5.

+1

'estende $' non ha senso. Pensavate che significasse lo stesso di '$ .extend ({...})'? – Bergi

+1

Se stai guardando le nuove funzionalità di Javascript, probabilmente non hai bisogno di jQuery. Esistono molte librerie UI standalone che non richiedono jQuery. Inoltre, esiste un sito Web speciale http://youmightnotneedjquery.com/ che spiega come passare da jQuery a funzioni native. –

risposta

10

$.fn è solo un oggetto. Non c'è magia quando si aggiunge una nuova proprietà al prototipo di $. Quindi, il codice $.fn.myPlugin = function() {} è uguale a $.prototype.myPlugin = function() {}.

$.fn === $.prototype; // true

Per essere in grado di chiamare una funzione sull'oggetto $ in modo standard ($('div').func()), è necessario aggiungere questa funzione per l'oggetto $.

Non lo si aggiunge al codice es6.

Così,

import $ from 'jquery'; 

export default class myPlugin extends $ { 
// Could i use constructor() method ??? 
} 

Means (quasi)

var myPlugin = function() {}; 

myPlugin.prototype = Object.create($.prototype); 

return { default: myPlugin }; 

Non sono sicuro che si dovrebbe estendere $ .fn, ma forse ne avete bisogno.

E con

import $ from 'jquery'; 
import myPlugin from 'myPlugin.es6'; 

significa

var $ = require('jquery'); 
var myPlugin = require('myPlugin'); // a reference to the 'export.default' object from 'myPlugin.es6' 

Pertanto, non v'è alcuna connessione tra $.fn oggetto e myPlugin funzione.

È necessario creare la connessione da qualche parte. Potrebbe essere in un modulo speciale come plugins dove si inietta tutti i plugin necessari nell'oggetto $.fn:

import $ from 'jquery'; 
import plugin1 from 'plugin1.es6'; // should contain 'name' 
import plugin2 from 'plugin2.es6'; 
... 
import plugin10 from 'plugin10.es6'; 

[plugin1, plugin2, ..., plugin10].forEach(plugin => $.fn[plugin.name] = plugin); 

Oppure si potrebbe aggiungere un metodo di 'inizializza' per l'oggetto esportato in 'myplugin.es6 ', e chiamalo prima del primo utilizzo: init($) { $.fn.myPlugin = myPlugin; }

E così via.

+0

Se una funzione non è anonima, ha una proprietà name. Quindi la tua soluzione sembra molto buona! Ho giocato con esso su [Rollup sandbox] (http://bit.ly/1T0Q4mU) –

+0

Ho finito per fare quasi la stessa cosa nel mio codice. Esportando per nome: 'export const myexport = {init: function ($) {/ * code here * /}}' poi 'importa {myexport} da './myexport.es6'; myexport.init ($) '. –

5

Si installano nuovi metodi sul prototipo jQuery in ES6 proprio come hai sempre fatto. Nulla è cambiato per loro. Non hai intenzione di sottoclasse jQuery, quindi non ha senso usare class o extends.

// myPlugin.es6: 
import $ from 'jquery'; 

$.fn.myPlugin = function() { 
    … 
}; 

// app.es6: 
import $ from 'jquery'; 
import 'myPlugin.es6'; 

$('div').myPlugin();