2012-04-24 29 views
31

Tôi đang thay đổi một dự án từ một cấu trúc mô-đun trình duyệt theo kiểu "cũ" sang "mới" browser- hay-server-side-javascript mô-đun cấu trúc với require.js.phương pháp gọi trong module RequireJs từ các phần tử HTML như bộ xử lý onclick

Trên client Tôi đang sử dụng một ngoại vi tổ chức jQuery, vì vậy tôi bắt đầu từ ví dụ họ đưa ra trong kỹ thuật "use priority config" của README:

<title>My Page</title> 
<script src="scripts/require.js"></script> 
<script> 
require({ 
    baseUrl: 'scripts', 
    paths: { 
     jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min', 
     jqueryui: ..., 
     ... 
     ... // bunch more paths here 
    }, 
    priority: ['jquery'] 
}, [ 'main' ]); 
</script> 

này được thực sự làm việc ổn thôi. Nhưng tôi muốn xuất chức năng từ chính sang trang web HTML. Ví dụ:

<a class="button" href="#" onclick="MyApi.foo();"> 
    <img src="foo.png" alt="foo" />Click for: <b>Foo!</b> 
</a> 

Trước khi lắp vào kiểu mô-đun bộ xử lý AMD, tôi đã tiếp xúc với chức năng từ các tập tin khác nhau của tôi bằng cách tạo ra một đối tượng từ điển trong không gian toàn cầu:

// main.js 

var MyApi = {}; 

jQuery(document).ready(function($) { 
    // ...unexported code goes here... 

    // export function via MyApi 
    MyApi.foo = function() { 
     alert("Foo!"); 
    }; 
}); 

Nhưng tôi không biết cách tiếp cận đúng trong require.js là gì. Có thể đặt các câu lệnh require vào HTML của các thẻ <script> và sau đó đặt tên mô-đun để nó có thể được sử dụng từ bên trong trang web không? Hoặc điều này luôn luôn được thực hiện tự động bên trong main.js, chẳng hạn như $('#foobutton').click(...)?

Trả lời

30

Một lợi ích từ việc sử dụng AMD là giảm nhu cầu về không gian tên. Cố gắng tạo ra chúng một lần nữa với RequireJS sẽ đi ngược lại các mẫu mà AMD khuyến khích.

Đối với việc sử dụng main.js, điều này chỉ thực sự phù hợp khi bạn có một ứng dụng trang và tất cả mã của bạn đều được tham chiếu từ một nơi. Bạn được tự do thực hiện các cuộc gọi bổ sung để yêu cầu và tải các mô-đun khác khi bạn cần chúng.

Sử dụng ví dụ của bạn từ trên cao, bạn có thể tiếp cận nó theo cách này:

foo.js

define(['jquery'], function($) { 

    // Some set up 
    // code here 

    // Return module with methods 
    return { 
     bar: function() { 

     } 
    } 


}); 

page.js

require(['foo'], function(foo) { 

    // jQuery loaded by foo module so free to use it 
    $('.button').on('click', function(e) { 
     foo.bar(); 
     e.preventDefault(); 
    }); 

}); 

Sau đó, trong yêu cầu trang của bạn tệp page.js có yêu cầu.

Sử dụng ví dụ của bạn ở trên:

require({ 
    // config stuff here 
}, [ 'page' ]); 

Hoặc tải nó trong trang tiếp tục xuống:

<script> 
    require(['page']); 
</script> 

Một số điểm bổ sung

  • Sử dụng mô hình trên, trang .js có thể dễ dàng yêu cầu nhiều khác mô-đun để tải các chức năng liên quan đến trang khác.

  • Nơi trước khi bạn đính kèm thành viên vào không gian tên chung của mình, bạn giờ chia mã đó thành các mô-đun riêng biệt có thể được sử dụng lại trên bất kỳ trang nào. Tất cả đều không phụ thuộc vào một đối tượng toàn cầu.

  • Sử dụng đòi hỏi theo cách này để đính kèm các sự kiện để các yếu tố DOM của bạn nhiều khả năng rely on the DOM Ready module sẽ được cung cấp bởi RequireJS

+0

Xin chào, cảm ơn (chỉ cần quay lại dự án này và xem chi tiết câu trả lời). Bạn đưa vào các từ lý do tại sao việc đặt mã trong onclick không phù hợp với phương pháp này; trình xử lý trực tiếp trong HTML của trang sẽ yêu cầu bất kỳ API nào họ gọi để có cùng tên được nhập trên tất cả các tệp .js được tải (er ... phải không?). Nhưng bởi mã thông báo đó ... trong mẫu này, không nên page.js phải đề cập rõ ràng về ánh xạ jquery thành '$' thay vì thừa hưởng rằng chỉ vì đó là những gì foo đã nhập nó như là? – HostileFork

+0

Tôi luôn nghĩ về các mô-đun theo nghĩa là chúng có thể sử dụng lại được, các bit được phân loại. Nhưng với cách tiếp cận này mọi thứ phải được ném vào một mô-đun và không có sự phân biệt rõ ràng giữa các công cụ thông thường như ràng buộc sự kiện và các mô-đun thực tế - nếu bạn hiểu ý tôi. Có không có cách nào khác? – backdesk

+0

Trong câu hỏi, DOM phụ thuộc vào đối tượng MMyApi toàn cầu. Trong câu trả lời này, mô-đun trang phụ thuộc vào DOM, cũng là toàn cục. Phải có một số loại phụ thuộc. Mà một trong những sử dụng có lẽ là một sự lựa chọn chủ quan. –

3

đặt onclick="" bên trong đánh dấu của bạn cảm thấy trình bày hỗn hợp dơ bẩn với nội dung. Tôi khuyên bạn nên thêm một khối <script> và đặt require vào trong đó và một lần bên trong cuộc gọi lại và bên trong một số khác bên trong $(document).ready() nếu cần, sau đó kết nối các trình xử lý sự kiện của bạn theo cách thông thường: $('#node').click(...). Nếu bạn có thể làm điều này một cách tổng quát đủ để nó có thể áp dụng cho nhiều trang, thì hãy đặt nó bên trong một tệp bên ngoài được rút gọn, kết hợp và lưu trữ. Nhưng thông thường, những điều này kết thúc bằng từng trang cụ thể, do đó, thẻ <script> ở cuối trang là giải pháp tốt để tránh yêu cầu tài nguyên bên ngoài khác.

+2

+1 * một vài ngày trước: -) * ... có trên bản trình bày và nội dung, mặc dù nó cảm thấy như lập trình web là như vậy gậy và keo rằng giá trị cụ thể của "thực hành tốt nhất" phức tạp thường là nặng hơn bởi phương pháp đơn giản. Tôi đã thấy một lập luận tương tự về bản mẫu HTML5 với một "khi nào chúng ta để cho công cụ này đi đến đầu của chúng tôi". (http://csswizardry.com/2011/01/the-real-html5-boilerplate/) Nhưng @ SimonSmith's * "nếu bạn định sử dụng require.js thì nhập vào phạm vi trang là xấu, và đó là những gì bạn ' d phải làm cho mã trong onclick để xem bất cứ điều gì "* có ý nghĩa với tôi trong một" nếu A sau đó B "cách ... – HostileFork

+0

Cá nhân, tôi nghĩ rằng tiện ích của việc có thể cho biết những gì một nút nào, mà không cần phải tìm kiếm mã và có lẽ vẫn không tìm thấy nó, mạnh hơn bất kỳ lợi thế có thể có của việc tách nó ra. Khi bạn nhìn thấy một thẻ nút với một "onclick" trong nó, không có đoán về những gì sẽ xảy ra khi người dùng nhấp vào nút đó. HTML không phải là bản trình bày thuần túy và sẽ không bao giờ có, và điều đó cũng ổn với tôi. – Jasmine

14

Bạn cũng có thể thiết lập các tài liệu tham khảo trên lớp cửa sổ javascript của.

Ở dưới cùng của các module ứng dụng window.MyApi = MyApi;

<a class="button" href="#" onclick="MyApi.foo();"></a>

2

Một giải pháp là chỉ cần sử dụng mã như thế (tất nhiên requirejs phải được thêm vào trang):

<input type="button" onclick="(function() { require('mymodule').do_work() })()"/> 
Các vấn đề liên quan