2012-04-17 25 views
5

Tôi đã bỏ qua javascript mãi mãi. Tôi bắt đầu sử dụng jQuery vài năm trước để tôi có thể nhận được. Nhưng khi tôi đã bắt đầu làm TDD hơn, tôi quyết định ngày hôm qua để thực sự nhảy vào javascript (và có thể coffeescript sau đó).Làm cách nào để mở rộng không gian tên javascript trên nhiều tệp?

Trong ứng dụng Biểu mẫu web ASP.NET của tôi, tôi có nhiều trang và hiện tại hầu hết các trang đó không có nhiều javascript. Tôi đang trong quá trình thay đổi điều đó. Tôi đang sử dụng Jasmine với Chutzpah để tạo ra các bài kiểm tra của tôi.

Tôi đã di chuyển cùng với các thử nghiệm của tôi đi qua và thất bại như mong đợi. Nhưng sau đó tôi muốn tạo ra một không gian tên vì vậy tôi sẽ không chà đạp khắp nơi trên toàn cầu.

Sau khi đọc bài viết này: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

tôi quyết định thử và sử dụng mô hình từ Chức năng tự thực hiện Anonymous: Phần 2 (Public Private &) của bài viết này. Nó dường như có sự linh hoạt nhất và dường như đóng gói mọi thứ rất tốt.

Tôi có thư mục có tên/Tập lệnh. Dưới thư mục đó là một số khung công tác tôi đang sử dụng như jQuery, jasmine, (twitter) bootstrap và modernizr. Tôi cũng có một thư mục con được gọi là/Trang web nơi tôi đang đặt mã của tôi cho trang web trong nhiều tệp dựa trên trang. (product.js, billing.js, vv)

Dưới/Script/Site Tôi đã thêm một thư mục con vào/Tests (hoặc Specs) có các tệp (product_test.js, billing_tests.js, v.v.).

Nếu không có không gian tên thì mọi thứ đều ổn. Tôi có tệp gad.js tôi đã tạo bằng chức năng trợ giúp padLeft. Sau đó tôi đã sử dụng padLeft toàn cục đó trong tệp .js khác. Các bài kiểm tra của tôi đều hiệu quả và tôi rất vui. sau đó tôi quyết định tìm ra các không gian tên và thay đổi kịch bản của tôi/trang web/utility.js để trông giống như:

(function (myns, $, undefined) { 
    //private property 
    var isSomething = true; 

    //public property 
    myns.something = "something"; 

    //public method 
    myns.padLeft = function (str, len, pad) { 
     str = Array(len + 1 - str.length).join(pad) + str; 

     return str; 
    }; 


    //check to see if myns exists in global space 
    //if not, assign it a new Object Literal 
}(window.myns= window.myns|| {}, jQuery)); 

Sau đó, trong tôi Scripts/trang web/thử nghiệm/utility_test.js Tôi có

/// <reference path="../utility.js" /> 

describe("Namespace myns with public property something", function() { 
    it("Should Equal 'something'", function() { 
     expect(myns.something).toEqual('something'); 
    }); 
}); 

Với bài kiểm tra cực kỳ đơn giản này, tôi đã mong đợi myns.something quay lại với giá trị chuỗi của 'cái gì đó'.

Không. Nó quay lại không xác định.

Vì vậy, làm cách nào để sử dụng không gian tên javascript trên nhiều tệp?

Xin lỗi vì đã giới thiệu dài, nhưng tôi thấy nó có thể giúp giải thích tại sao lý do tại sao của tôi làm theo cách này. Tôi cũng đặt tất cả điều này bởi vì tôi mở để nghe ý tưởng về cách thiết lập này là hoàn toàn sai hoặc một phần sai hoặc bất cứ điều gì.

Cảm ơn bạn đã dành thời gian đọc câu hỏi này.

CẬP NHẬT: SOLVED Cảm ơn tất cả vì sự giúp đỡ của bạn. Sự giúp đỡ nhiều nhất đến từ người bình luận @ T.J. Crowder. Tôi không biết công cụ jsbin đã tồn tại và sau khi bị thuyết phục rằng mã tôi đưa vào ở trên đã được đưa vào công cụ và kết quả là đúng, tôi biết có điều gì đó phải tắt trong môi trường của tôi.

Liên kết trong câu trả lời được chấp nhận cũng đã giúp tôi rất nhiều. Sau khi thấy rằng cú pháp và logic là nhất quán và làm việc, tôi chỉ phải xác định những gì đã xảy ra về thiết lập của tôi. Tôi xấu hổ khi nói rằng đó là tôi đi qua trong jQuery nhưng trong khai thác thử nghiệm của tôi, nơi tôi đã cố gắng để có được điều này để làm việc tôi đã không thực sự sử dụng jQuery. Điều này có nghĩa là các mô-đun đã không thực sự được nạp - vì vậy myns chưa bao giờ được thiết lập.

Cảm ơn mọi người. Hy vọng rằng điều này có thể hữu ích cho ai đó trong tương lai. Nếu bạn sử dụng ở trên, hãy đảm bảo bạn bao gồm đối tượng jQuery. Các tùy chọn khác là không vượt qua trong jQuery và loại bỏ $ từ danh sách param.

+2

Những gì bạn đã hiển thị sẽ hoạt động được cung cấp cả 'utility.js' và' utility_test.js' được bao gồm và theo thứ tự đó. Ví dụ: http://jsbin.com/idofog –

+0

cảm ơn bạn đã giới thiệu dài, nó giúp chúng tôi tìm ra những gì bạn muốn :-) – Philipp

+0

@ T.J.Crowder Cảm ơn bạn. Thùng rác đó hoạt động nhưng tôi không thể thấy tại sao nó lại khác trong môi trường của tôi. Tôi không biết về jsbin, vì vậy cảm ơn cho điều đó là tốt! Tôi sẽ thử một vài thứ trong hộp cát đó. –

Trả lời

0

Javascript không có không gian tên, tôi đoán bạn có vấn đề với phạm vi biến và điều này cũng tương tự như các ngôn ngữ khác, những gì bạn đang nói về là đối tượng. Bạn có thể sử dụng

window.myns.something 

Hàm đầu tiên đã thêm đối tượng của bạn vào đối tượng cửa sổ và đối tượng cửa sổ có thể truy cập từ mọi nơi.

+0

sử dụng thuộc tính lồng nhau như thế này là một cách phổ biến để mô phỏng các không gian tên trong Javascript. – Alnitak

+0

Tôi biết nhưng như bạn đã nói, đó là "mô phỏng" các không gian tên. Có sự khác biệt rất lớn đối với các không gian tên, ví dụ: trong .NET, nhưng nó tương tự như đối tượng trong .NET (ngoại trừ việc thay đổi giao diện lúc chạy) – Philipp

+0

@PhilippMehrwald Cảm ơn. Tôi nên có được rõ ràng hơn về nói "mô phỏng không gian tên". Với mẫu tôi đang cố gắng tránh sử dụng window.myns.something. Thậm chí thay đổi nó thành điều đó trong tập tin thử nghiệm của tôi không thành công. Vì vậy, tôi phải có cái gì khác sai. Cảm ơn! –

1

Hãy thử đặt tuyên bố không gian tên của bạn bên ngoài của cuộc gọi chức năng:

myns = window.myns || {}; 
(function(myns, $, undefined) { 
    ... 
}(myns, jQuery)); 

cú pháp hiện tại của bạn dường như là hoàn toàn hợp lệ, nhưng phá vỡ dòng ra có thể giúp tìm ra những gì đang xảy ra sai với phạm vi biến của bạn.

+0

Cảm ơn, tôi đã thử nó nhưng có cùng kết quả. Có vẻ như tôi có thứ gì đó khác. Đào sâu vào nó ... –

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