2013-01-07 16 views
6

Giả sử tôi muốn sử dụng jquery cùng với một plugin jquery tiêu chuẩn, không được kích hoạt chuẩn đã được xác định bằng cách sử dụng đóng tiêu chuẩn: (function($))($.fn.myplugin = { ... })(jQuery); và tất cả đều nằm bên trong một số js/libs/jquery/jquery.myplugin.js.Cách đúng để tải các plugin jQuery tương thích không phải của AMD trong require.js bằng jQuery ở chế độ noConflict?

tôi sử dụng cấu hình này:

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'] 
    } 
}); 

tôi tải jQuery trong không mâu thuẫn chế độ trong libs/jquery/jquery-noconflict.js, becase Tôi không muốn làm ô nhiễm không gian tên toàn cầu:

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

và đây là cách tôi tải app.js chính của tôi:

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? 
}); 

Bây giờ, đây là vấn đề tôi đang gặp - trong khi tôi có thể tất cả các thư viện được định nghĩa ở trên mà không có bất kỳ vấn đề gì, tôi không thể tìm ra cấu hình shim chính xác để tải các plugin jquery không được kích hoạt AMD.

Tôi đã cố gắng thiết lập jquery-myplugindeps của số jquery (và cách khác) nhưng tôi không bao giờ làm việc được.

Nó có vẻ như tôi đang gặp vấn đề với các tình huống sau:

  1. jQuery tải trong không mâu thuẫn chế độ.
  2. chạy mã plugin, mở rộng phiên bản của jQuery ở trên
  3. Tôi có thể sử dụng $ trong ứng dụng của mình, được mở rộng bằng mã plugin, vì vậy $ .myplugin có sẵn.

Tôi đã thấy câu hỏi tương tự nổi xung quanh nhưng không ai trong số họ thực sự giải quyết vấn đề này chỉ đưa ra gợi ý mơ hồ như "sử dụng shim config" ...

Sửa

Tôi cũng đã cố gắng sử dụng

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

Và trong khi các phương thức plugin có sẵn khi được nạp dưới dạng mô-đun AMD theo cách này, tôi vẫn không thể truy cập: $('.class').myplugin() as de lỗi $ đối tượng đã không được mở rộng với mã myplugin.

+0

Bạn vẫn gặp sự cố với điều này? – Louis

+0

phụ thuộc mô-đun phải được thể hiện trong một mảng: 'define (['dep1', 'dep2' ... 'depn'], hàm (dep1, dep2, ... depn) {});' như được mô tả [ở đây] (http://requirejs.org/docs/errors.html#requireargs) – Vikram

+0

bắt tốt, nhưng đó chỉ là nhầm lẫn của tôi trên stackoverflow, vấn đề cơ bản vẫn còn đó – rochal

Trả lời

3

Sử dụng jQuery.noConflict(true) xóa biến số toàn cầu jQuery. Khi plugin của bạn tải, nó sẽ cố gắng truy cập jQuery, nhưng không thể, gây ra lỗi này.

Nếu plugin của bạn là một mô-đun, nó có thể truy cập vào jQuery dưới dạng phụ thuộc. Hoặc bạn có thể để jQuery có sẵn dưới dạng toàn cầu.

+0

Cảm ơn Sean, tôi biết những gì xảy ra ở đây và những gì tôi muốn phải làm là sử dụng require.js một cách chính xác mà không có mô-đun nào nên tạo biến toàn cầu và tất cả các mô-đun khác tải jQuery làm phụ thuộc nếu cần. – rochal

+1

Nếu đúng như vậy, bạn sẽ không thể sử dụng các plugin không được chuyển đổi. Nếu bạn muốn jQuery chỉ có sẵn như một mô đun, thì bạn sẽ phải chuyển đổi các trình cắm thêm để sử dụng 'define()', để khai báo một sự phụ thuộc vào jQuery. –

+1

Cảm ơn Sean, tôi đã ấn tượng rằng cấu hình shim vẫn cho phép bạn xử lý các mô-đun không được AMD kích hoạt mà không sử dụng các phụ thuộc toàn cầu. IMHO nó hút thời gian lớn mà bạn phải sửa đổi mã bên thứ 3 để làm cho nó hoạt động với AMD/yêu cầu .. – rochal

-1

Thứ nhất, bảo đảm rằng "path/to/jquery-myplugin" thực sự kéo dài window.jQuery và không $

noConflict() lá window.jQuery đối tượng được xác định nhưng unbinds chính nó từ window.$ Trên một số trình duyệt mới window.$ được xây dựng trong bí danh cho quê hương document.querySelectorAll chức năng.

Thứ hai, myplugin của bạn KHÔNG cần phải trả lại chính nó, vì nó không thể được sử dụng bởi chính nó. Vì nó mở rộng jQuery, trả về jQuery từ cuộc gọi myplugin.

Cuối cùng, "đường dẫn/đến/jquery-myplugin" KHÔNG phải là mô-đun. Đó là một tệp JS đơn giản. Có thể RequireJS cố gắng tải nó như một mô-đun và không tìm thấy cuộc gọi define(), điều này dẫn đến sự lộn xộn. Hãy thử thực sự thêm phần mở rộng tệp ".js" vào tham chiếu để báo hiệu tới RequireJS rằng nó cần sử dụng "js!" plugin để tải tài nguyên.

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

Đó là sai. Mã cho noConflict là ở đây: '' 'javascript noConflict': function (sâu) { \t \t if (cửa sổ $ === jQuery.) { \t \t \t cửa sổ $ = $ _;. \t \t} \t \t if (sâu && window.jQuery === jQuery) { \t \t \t cửa sổ.jQuery = _jQuery; \t \t} \t \t return jQuery; \t}, '' '' Khi bạn chuyển thông số "sâu", nó cũng hủy liên kết window.jQuery, vì vậy bạn có thể chạy nhiều phiên bản trên cùng một trang. – Ped

-1

Tôi đã gặp vấn đề tương tự như bạn hôm nay. Dưới đây là làm thế nào tôi có thể sửa chữa nó:

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"]); 

Bây giờ trong ứng dụng của tôi/main.js nộp tôi có thể làm như sau:

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

Ý tưởng ở đây là để lộ jQuery tạm thời trước khi cắm mã được thực thi . Cho đến nay tôi đã không kiểm tra các giải pháp trong một môi trường lớn hơn với rất nhiều mô-đun để tải, vì vậy tôi không thể đảm bảo nó sẽ làm việc trong thời gian dài;)

Sửa

Giải pháp này giành 't làm việc !! Vì requirejs không tải các tập lệnh tuần tự, nên có thể tải tệp js của plugin xuống trước khi jquery gây ra lỗi thực thi. Xin lỗi vì điều này.

Nếu ai đó có ý tưởng khác ...

Các vấn đề liên quan