2012-02-15 30 views
32

Khi tôi tạo tệp coffeescript mới, tôi không thể truy cập mã trong mã được biên dịch từ tệp khác bởi vì nó được gói trong một phạm vi chức năng nào đó. Ví dụ:Nhiều tập tin liên lạc với coffeescript

CoffeeScript:

class ChatService 
    constructor: (@io) -> 

tạo javascript:

(function() { 
    var ChatService;  
    ChatService = (function() {  
    function ChatService(io) { 
     this.io = io; 
    }  
    return ChatService;  
    })();  
}).call(this); 

Khi cố gắng để gọi ChatService trong tập tin khác, nó không được định nghĩa. Làm cách nào để xử lý nhiều tệp bằng coffeescript?

+0

Nếu bạn đang sử dụng Rails, bạn phải đảm bảo rằng bất kỳ tập tin coffeescript phụ thuộc nào được gọi là * trước * bạn thử và tham khảo nó. Khi bạn đặt chỉ thị "yêu cầu" trong các tệp thực sự cần đến các tệp khác, bạn sẽ có quyền truy cập vào các biến, v.v. –

Trả lời

56

Tùy thuộc vào việc đây là mã phía máy khách hay phía máy chủ, có hai cách tiếp cận hơi khác nhau.

Client-side: Ở đây chúng ta đính kèm những điều mà nên có sẵn trên các tập tin để không gian tên toàn cầu (window) như sau:

class window.ChatService 
    constructor: (@io) -> 

Sau đó, trong tập tin khác cả ChatServicewindow.ChatService sẽ cho phép truy cập vào các lớp .


Phía máy chủ: Ở đây chúng tôi phải sử dụng exportsrequire. Trong tập tin ChatService.coffee, bạn sẽ phải như sau:

class exports.ChatService 
    constructor: (@io) -> 

Sau đó, để có được vào nó từ tập tin khác, bạn có thể sử dụng:

ChatService = require('ChatService.coffee').ChatService 

Lưu ý: Nếu có nhiều lớp học mà bạn nhận được từ ChatService.coffee, đây là một nơi dict CoffeeScript của giải nén thực sự tỏa sáng, chẳng hạn như:

{ChatService, OtherService} = require('ChatService.coffee') 

Cả hai: Về cơ bản, chúng tôi chọn có nên chạy mã phía máy chủ hoặc phía máy khách dựa trên môi trường chúng tôi đang sử dụng hay không.Một cách phổ biến để làm điều đó:

class ChatService 
    constructor: (@io) -> 

if typeof module != "undefined" && module.exports 
    #On a server 
    exports.ChatService = ChatService 
else 
    #On a client 
    window.ChatService = ChatService 

Để có được nó:

if typeof module != "undefined" && module.exports 
    #On a server 
    ChatService = require("ChatService.coffee").ChatService 
else 
    #On a client 
    ChatService = window.ChatService 

Các khác khoản của khối thứ hai có thể được bỏ qua, kể từ khi ChatService đã đề cập đến các tài liệu tham khảo kèm theo window.

Nếu bạn đang đi để xác định rất nhiều lớp trong tập tin này, nó có thể được dễ dàng hơn để định nghĩa chúng như:

self = {} 

class self.ChatService 

Và sau đó đính kèm chúng như module.exports = self trên máy chủ và _.extend(window, self) trên máy khách (thay thế _.extend bằng một chức năng khác extend khi thích hợp).

+1

+1 cho phía node.js của sự vật. –

+2

Cảm ơn bạn đã cung cấp cho cả hai phương thức tiếp cận node.js và phía máy khách, tôi cần cả hai. –

+0

Giống như câu trả lời từ "mu quá ngắn", bạn cũng có thể thực hiện export.App.ClassName. Tôi đoán bạn có thể gọi phần Ứng dụng của "không gian tên" đó. Nêu tôi sai vui long chân chỉnh tôi. – Chris

23

Cách tiếp cận thông thường là để xác định một không gian tên toàn cầu trong window:

window.App = { } 

Điều đó sẽ đi đâu trong mã khởi tạo ứng dụng của bạn trước khi bất cứ điều gì khác xảy ra. Và sau đó, cho lớp học của bạn:

class App.ChatService 
    constructor: (@io) -> 

đó cho phép bạn để tham khảo lớp học của bạn thông qua App bất cứ nơi nào bạn muốn và bạn không cần phải lo lắng về việc gây ô nhiễm không gian tên toàn cầu:

chatter = new App.ChatService 

Nếu bạn muốn để làm cho ChatService thực sự toàn cầu của bạn thì bạn có thể sử dụng class window.ChatService nhưng tôi khuyên bạn nên chống lại điều đó ngoại trừ trong các ứng dụng tầm thường nhất.

AFAIK, node.js có thứ gì đó tương tự như window nhưng tôi không đủ quen thuộc với node.js để cho bạn biết đó là gì.

+1

Trong node.js, bạn xuất các ký hiệu bằng cách đính kèm chúng vào 'xuất'. Trong một mô-đun: exports.ChatService = ChatService; Mặt khác: ChatService = require ("./ chat"). ChatService. –

+0

@Linus: Cảm ơn, tôi nghĩ Aaron Dufour đã bao phủ điều đó trước khi tôi bắt đầu. –

0

Phân tách các lớp của bạn bằng các không gian tên và sử dụng cake để biên dịch tất cả chúng trong một (hoặc nhiều) tệp .js kết quả. Cakefile được sử dụng như cấu hình để kiểm soát thứ tự các tập lệnh cà phê của bạn được biên dịch - khá tiện dụng với các dự án lớn hơn.

Cake là khá dễ dàng để cài đặt và thiết lập, cách gọi bánh từ vim trong khi bạn đang chỉnh sửa dự án của bạn là sau đó chỉ cần

:!cake build 

và bạn có thể làm mới trình duyệt của bạn và xem kết quả.

Vì tôi cũng đang bận học cách tốt nhất để cấu trúc các tệp và sử dụng coffeescript kết hợp với xương sống và bánh, tôi đã tạo ra một small project on github để giữ nó làm tài liệu tham khảo cho bản thân, có thể nó sẽ giúp bạn bánh và một số thứ cơ bản. Tất cả các tệp được biên soạn nằm trong thư mục www để bạn có thể mở chúng trong trình duyệt của mình và tất cả các tệp nguồn (ngoại trừ cấu hình bánh) nằm trong thư mục src. Trong ví dụ này, tất cả các tệp .coffee được biên dịch và kết hợp trong một tệp .js đầu ra sau đó được đưa vào html.

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