2012-10-02 34 views
12

tôi đang tích hợp RequireJS trong một CMS vì vậy tôi đặt này trên dưới cùng của trang mẫu của tôi:Tải mô đun requireJS trong nội dung HTML?

<html> 
<body> 
    {Placeholder1} 
    <script src="scripts/require.js" data-main="scripts/main"></script> 
    {Placeholder2} 
</body> 
</html> 

Sau đó, trên mỗi trang, tôi muốn tạo một hàm đó thúc đẩy RequireJS. Vì vậy, tôi đã cố gắng đặt này trên dưới cùng của trang:

<html> 
<body> 
    <h1>Home</h1> 
    <div class="slider">Slider content</div> 

    <script src="scripts/require.js" data-main="scripts/main"></script> 

    <script type="text/javascript"> 
     require([ 
     'jquery', 
     'utils', 
     'slider' 
     ], function ($, utils, slider) { 
     slider.start(); 
     }); 
    </script> 
</body> 
</html> 

Nhưng tôi nhận được của 404 trên jquery, utils và các tập tin trượt js. Có vẻ như nó không đọc cấu hình main.js của tôi mà tôi có:

require.config({ 
    paths: { 
     jquery: 'libs/jquery-1.8.1.min', 
     utils: 'libs/utils', 
     slider: 'libs/jquery.slider.min' 
    }, 
    shim: { 
     slider: ['jquery'] 
    } 
}); 

require([ 'utils' ], function (utils) { 
    utils.init(); 
}); 

Tôi đã thử tải RequireJS và chính trong đầu trang, nhưng có kết quả không phù hợp theo cách đó. Đôi khi jquery, utils và thanh trượt sẽ được tải trong thời gian và thời gian khác không. Nó giống như nội tuyến "yêu cầu" ở dưới cùng của trang là không nhận thức được chính RequireJS trên trang hoặc các quy tắc phụ thuộc, nhưng các điểm ngắt của tôi trong main.js vì vậy tôi biết nó đang được gọi. Có phải vì main.js được tải không đồng bộ nhưng khối "yêu cầu" nội tuyến của tôi ở cuối trang được tải trên trang kết xuất? Làm thế nào để tôi có được điều này?

Tôi đã sử dụng thành công RequireJS trước đây nhưng không có CMS. Tôi luôn luôn sử dụng "xác định" và có mô-đun luôn được gọi là không đồng bộ, nhưng không bao giờ phải gọi hàm RequireJS nội tuyến như thế này. Bất kỳ ý tưởng về cách chính xác để làm điều này?

Trả lời

12

Điều quan trọng ở đây là các tùy chọn cấu hình được thiết lập trước khi bất kỳ mô-đun được yêu cầu. Như bạn đã xác định đúng, có điều kiện chủng tộc có nghĩa là các tùy chọn cấu hình trong main.js của bạn không được tải đúng lúc. Cách đơn giản nhất vòng nó sẽ được đặt nội tuyến tùy chọn cấu hình trước khi kịch bản require.js được tải.

<script> 
var require = { 
    baseUrl: <?= $someVar ?>, 
    paths: { 
     // etc 
    } 
} 
</script> 
<script src="scripts/require.js" data-main="scripts/main"></script> 

Tiếp tục xuống trang:

<script> 
    require([ 
     'jquery', 
     'utils', 
     'slider' 
     ], function ($, utils, slider) { 
     slider.start(); 
     }); 
</script> 

Xem thêm How does RequireJS work with multiple pages and partial views?

+1

Sự cố với thiết lập này là tài nguyên có thể được tải hai lần khi tập lệnh/tệp chính chứa nhiều mô-đun (thường là trường hợp khi trình tối ưu hóa r.js được sử dụng). Đây là một vấn đề đặc biệt nếu đây là một tệp không sử dụng định nghĩa của require. Giả sử rằng tệp 'scripts/main' chứa mô-đun LESS JS. Hơn nữa, giả sử rằng yêu cầu nội tuyến yêu cầu cũng yêu cầu mô-đun này.Bây giờ nếu cuộc gọi nội tuyến được truy cập trước khi kịch bản lệnh chính được tải (trường hợp thường xảy ra) thì mô-đun sẽ thu được hai lần. Nếu nội dung không phải là mô-đun AMD, điều này có thể dẫn đến lỗi! –

6

Có vẻ như những gì đang xảy ra là main.js đang được tải không đồng bộ trong khi yêu cầu nội tuyến được gọi ngay lập tức. Đây là lý do tại sao có kết quả không phù hợp. Giải pháp là KHÔNG sử dụng thuộc tính data-main và gọi tệp main.js thông qua thẻ script bên dưới thẻ script require.js.

Bạn vẫn có thể xác định baseUrl từ tập tin main.js nạp bằng cách làm này trong đó:

//DETERMINE BASE URL FROM CURRENT SCRIPT PATH 
var scripts = document.getElementsByTagName("script"); 
var src = scripts[scripts.length-1].src; 
var baseUrl = src.substring(src.indexOf(document.location.pathname), src.lastIndexOf('/')); 

//CONFIGURE LIBRARIES AND DEPENDENCIES VIA REQUIREJS 
require.config({ 
    baseUrl: baseUrl, 
.... 
+0

Hoặc bạn có thể đặt mã nội tuyến của bạn vào main.js nộp thay thế. Hoặc bạn có thể đặt đường dẫn của bạn xác định vào một khối nội tuyến của mã. – dqhendricks

+0

Một trong những lý do để sử dụng RequireJS là tránh sự phụ thuộc vào các biến toàn cục, vì vậy, tránh làm điều này. –

+0

@Simon, thx để được tư vấn. Với hệ thống CMS rất khó để tránh điều này. Theo tôi, hầu như tất cả CMS đều lỗi thời. – Basem

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