2013-01-07 3 views
6

Angenommen, ich möchte jquery zusammen mit einem standardmäßigen, nicht amd-fähigen jquery-Plugin verwenden, das mit Standard-Closure definiert wurde: (function($))($.fn.myplugin = { ... })(jQuery); und alles innerhalb eines .Korrektes Laden von nicht-AMD-kompatiblen jQuery-Plugins in require.js mit jQuery im noConflict-Modus?

Ich benutze diese config:

require.config({ 
    baseUrl: 'js/', 
    paths: { 
    'jquery':   'libs/jquery/jquery-noconflict', 
    'underscore':  'libs/underscore/underscore', 
    'backbone':  'libs/backbone/backbone', 
    'jquery-myplugin': 'libs/jquery/jquery.myplugin' 
    }, 
    shim: { 
    'backbone': { 
     deps: ['underscore', 'jquery'], 
     exports: 'Backbone' 
    }, 
    'jquery-myplugin': { 
    deps: ['jquery'] 
    } 
}); 

ich jQuery laden in No-Konflikt-Modus in libs/jquery/jquery-noconflict.js, becase ich globalen Namensraum nicht verschmutzen wollen:

define(['libs/jquery'], function() { 
    return jQuery.noConflict(true); 
}); 

und das ist, wie ich mein Haupt app.js laden:

define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'jquery-myplugin'], 
function($, _, Backbone, MyPlugin){ 
    //MyPlugin is always undefined, not even sure if 
    //I should be passing it here if it only extends jQuery? 
}); 

Nun, hier ist das Problem, ich erlebe - während ich kann u Wenn Sie alle oben definierten Bibliotheken ohne Probleme haben, konnte ich die korrekte shim Konfiguration nicht herausfinden, um nicht-AMD fähige jquery plugins zu laden.

Ich habe versucht, jquery-myplugin als deps der jquery (und anders herum), aber ich konnte es nie funktionieren.

Es scheint, wie ich Problem mit dem folgenden Szenario mit bin:

  1. jQuery Lasten in No-Konflikt-Modus.
  2. Plugin-Code läuft, erweitern die Instanz der jQuery über
  3. Ich kann $ innerhalb meiner Anwendung, erweitert durch den Plugin-Code, so $ .myplugin ist verfügbar.

Ich habe im Umlauf ähnliche Fragen gesehen, aber keiner von ihnen löst tatsächlich dieses Problem nur vage Vorschläge wie „Einsatz Shim config“ ...

bearbeiten

geben auch ich versucht, mit

"jquery-myplugin": { 
    deps: ["jquery"], 
    exports: "jQuery.fn.myplugin" 
} 

Und während Plugin Methoden einmal sind als AMD-Modul auf diese Weise geladen wird, kann ich noch nicht Zugang: $('.class').myplugin() als de fault $ object wurde nicht mit myplugin code erweitert.

+0

Haben Sie immer noch Probleme damit? – Louis

+0

Modulabhängigkeiten sollten in einem Array ausgedrückt werden: 'define (['dep1', 'dep2' ... 'depn'], Funktion (dep1, dep2, ... depn) {});' wie beschrieben [hier] (http://requirejs.org/docs/errors.html#requireargs) – Vikram

+0

guter Haken, aber das war nur mein Tipp auf Stackoverflow, das zugrunde liegende Problem ist immer noch da – rochal

Antwort

3

Mit jQuery.noConflict(true) wird die globale Variable jQuery entfernt. Wenn Ihr Plugin geladen wird, versucht es auf jQuery zuzugreifen, kann dies jedoch nicht, was diesen Fehler verursacht.

Wenn Ihr Plugin ein Modul war, konnte es Zugriff auf jQuery als Abhängigkeit erhalten. Oder Sie könnten jQuery als global verfügbar lassen.

+0

Danke Sean, ich weiß was hier passiert und was ich will Zu tun ist, require.js korrekt zu verwenden, wenn keines der Module eine globale Variable erstellen sollte und alle anderen Module jQuery als Abhängigkeit laden, falls erforderlich. – rochal

+1

Wenn das der Fall ist, können Sie nicht konvertierte Plugins nicht verwenden. Wenn Sie möchten, dass jQuery nur als Modul verfügbar ist, müssen Sie die Plugins in 'define()' konvertieren, um eine Abhängigkeit von jQuery zu erklären. –

+1

Danke Sean, ich hatte den Eindruck, dass shim config immer noch die Möglichkeit bietet, nicht AMD-fähige Module ohne globale Abhängigkeiten zu verwenden. IMHO saugt es viel Zeit, dass Sie 3rd Party Code ändern müssen, um es mit AMD/require zu bekommen. – rochal

-1

Zuerst versichern, dass "path/to/jquery-myplugin" tatsächlich erweitert window.jQuery und nicht $

noConflict() verlässt window.jQuery Objekt definiert, sondern entbindet sich von window.$ Auf einigen neuen Browser window.$ für native in alias gebaut document.querySelectorAll Funktion.

Zweitens muss Ihr Myplugin NICHT selbst zurückgeben, da es nicht selbst verwendet werden kann. Da es erweitert jQuery, geben Sie jQuery von Myplugin Anruf zurück.

Schließlich ist "Pfad/zu/jquery-myplugin" kein Modul. Es ist eine einfache JS-Datei. Es ist möglich, RequireJS versucht, es wie ein Modul zu laden und nicht define() Anruf finden, was zu Unordnung führt. Versuchen Sie, der Referenz ".js" -Dateierweiterung hinzuzufügen, um RequireJS zu signalisieren, dass sie "js!" Verwenden muss. Plugin um die Ressource zu laden.

require.config({ 
    paths: { 
     "jquery": "path/to/jquery", 
     "jquery-myplugin": "path/to/jquery-myplugin.js" 
    }, 
    shim: { 
     "jquery": { 
      init: function() { 
      return window.jQuery.noConflict(); 
      }, 
     "jquery-myplugin": { 
      deps: ['jquery'] 
      init: function($) { 
      return $; 
      }, 
     } 
    } 
}); 
+0

Das ist falsch. Der Code für noConflict ist hier: '' '' Javascript noConflict: function (tief) { \t \t if (Fenster $ === jQuery.) { \t \t \t Fenster $ = $ _;. \t \t} \t \t if (tief && window.jQuery === jQuery) { \t \t \t Fenster.jQuery = _jQuery; \t \t} \t \t Zurück jQuery; \t}, '' '' Wenn Sie den Parameter "deep" übergeben, wird window.jQuery ebenfalls deaktiviert, sodass Sie mehrere Versionen auf derselben Seite ausführen können. – Ped

-1

hatte ich das gleiche Problem wie Sie heute. Hier ist, wie ich es beheben könnte:

requirejs.config({ 
    "baseUrl": "js/lib", 
    "paths": { 
     "app": "../app" 
    } 
}); 

// Final version of jQuery with all needed plugins. 
define("jquery", ["jquery-core", "myplugin"], function(jqCore) { 
    return jqCore; 
}); 

// Define core jQuery module. 
define("jquery-core", ["jquery-1.9.1.min"], function() { 
    return jQuery.noConflict(true); 
}); 

// This module exposes jquery module to the global scope and returns previous defined version. 
define("jq-global", ["jquery-core"], function(jqCore) { 
    var tmp = jQuery; 
    jQuery = jqCore; 
    return tmp; 
}); 

// Define your plugin here, and don't forget to reset previous jQuery version. 
define("myplugin", ["jq-global", "jquery.myplugin"], function(jqGlobal, jqPlugin) { 
    jQuery = jqGlobal; 
}); 

// Load the main app module to start the app 
requirejs(["app/main"]); 

Jetzt in meiner app/main.js Datei ich tun kann, die folgenden:

define(["jquery"], function($) { 
    $('body').myplugin(); 
}); 

Die Idee hier ist jQuery vorübergehend aussetzen, bevor Code-Plugin ausgeführt wird . Bisher habe ich nicht die Lösung in einer größeren Umgebung testen, mit viel mehr Module zu laden, also kann ich es nicht garantieren, wird auf lange Sicht funktionieren;)

bearbeiten

Diese Lösung gewonnen arbeite nicht !! Da requirejs die Skripte nicht sequentiell lädt, ist es möglich, dass die js-Datei des Plugins vor jquery geladen wird, wodurch die Ausführung fehlschlägt. Das tut mir leid.

Wenn jemand eine andere Idee hat ...

Verwandte Themen