2012-04-17 12 views
5

Zignorowałem javascript na zawsze. Zacząłem używać jQuery kilka lat temu, więc mogłem sobie poradzić. Ale jak zacząłem robić TDD więcej zdecydowałem wczoraj, aby naprawdę zanurzyć się w javascript (i prawdopodobnie coffeescript po tym).Jak rozłożyć przestrzeń nazw javascript na wiele plików?

W mojej aplikacji ASP.NET Web Forms mam wiele stron i obecnie większość z tych stron nie ma dużo javascript. Jestem w trakcie zmiany tego. Używam Jasmine z Chutzpah do tworzenia moich testów.

Poruszałem się wraz z testami, które przeszły testy i przeszły zgodnie z oczekiwaniami. Ale wtedy chciałem stworzyć przestrzeń nazw, żeby nie deptać całej globalnej przestrzeni.

Po przeczytaniu tego artykułu: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

postanowiłem spróbować i skorzystać z wzoru z Self-Wykonywanie Anonymous Funkcja: część 2 (Public & prywatna) części artykułu. Wydaje się, że ma największą elastyczność i wydaje się dobrze enkapsulować.

Mam folder o nazwie/Scripts. W tym folderze są niektóre z frameworków, których używam, takich jak jQuery, jaśmin, (twitter) bootstrap i modernizator. Mam też podfolder o nazwie/Site, w którym umieszczam mój kod witryny w wielu plikach na podstawie strony. (product.js, billing.js, itp.)

Under/Scripts/Site Dodałem podfolder do/Tests (lub Specs), które mają pliki (product_test.js, billing_tests.js, itp.).

Bez przestrzeni nazw wszystko jest w porządku. Mam utworzony plik utility.js z funkcją pomocniczą padLeft. Następnie użyłem tego globalnego padLeft w innym pliku .js. Moje testy sprawdziły się i byłem szczęśliwy. I wtedy postanowił dowiedzieć się nazw i zmienił moje scripts/site/utility.js wyglądać:

(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)); 

potem w moich scripts/site/tests/utility_test.js mam

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

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

Dzięki temu niezwykle prostemu testowi oczekiwałem, że myns.something powróci z wartością ciągu "coś".

Nie dotyczy. Wraca niezdefiniowana.

Jak mogę używać przestrzeni nazw javascript w wielu plikach?

Przepraszam za długie wprowadzenie, ale pomyślałem, że może to pomóc w wyjaśnieniu, dlaczego robię to w ten sposób. Dodałem to wszystko, ponieważ jestem otwarty na wysłuchanie pomysłów na temat tego, jak ta konfiguracja jest całkowicie błędna lub częściowo błędna.

Dziękujemy za poświęcenie czasu na przeczytanie tego pytania.

UPDATE: SOLVED Dziękuję wszystkim za pomoc. Najczęściej pomoc pochodzi od komentatora @ T.J. Crowder. Nie wiedziałem, że narzędzie jsbin istnieje i po upewnieniu się, że kod, który umieściłem powyżej, został umieszczony w narzędziu, a wyniki były poprawne. Wiedziałem, że coś musi być wyłączone w moim środowisku.

Link w zaakceptowanej odpowiedzi również bardzo mi pomógł. Po stwierdzeniu, że składnia i logika były spójne i działające, musiałem po prostu określić, co było w mojej konfiguracji. Wstydzę się mówić, że to ja przechodzę w jQuery, ale w mojej uprzęży testowej, w której próbowałem ją uruchomić, w rzeczywistości nie korzystałem z jQuery. Oznaczało to, że moduł nie był ładowany - więc myns nigdy nie został ustawiony.

Dziękuję wszystkim. Mam nadzieję, że może to być pomocne dla kogoś w przyszłości. Jeśli korzystasz z powyższych, upewnij się, że umieściłeś obiekt jQuery. Drugą opcją jest pominięcie jQuery i usunięcie $ z listy parametrów.

+2

To, co pokazałeś, powinno zadziałać, jeśli dołączone są zarówno pliki "utility.js', jak i" utility_test.js ", w tej kolejności. Przykład: http://jsbin.com/idofog –

+0

dziękuję za długie wprowadzenie, pomaga nam dowiedzieć się, co chcesz :-) – Philipp

+0

@ T.J.Crowder Dzięki. Ten kosz działa, ale nie rozumiem, dlaczego jest inny w moim środowisku. Nie wiedziałem o jsbin, więc dzięki za to również! Zamierzam wypróbować kilka rzeczy w tej piaskownicy. –

Odpowiedz

0

Javascript nie ma przestrzeni nazw, domyślam się, że masz problemy ze zmiennymi zakresami i jest to podobne do innych języków, o których mówisz, są obiektami. Pierwsza funkcja już dodaje obiekt do obiektu okna, a obiekt okna jest dostępny z dowolnego miejsca.

+0

używanie zagnieżdżonej właściwości, takiej jak ta, jest popularnym sposobem emulacji przestrzeni nazw w JavaScript. – Alnitak

+0

Wiem, ale jak powiedziałeś, "emuluje" przestrzenie nazw. Istnieją ogromne różnice między obszarami nazw, np. w .NET, ale jest podobny do obiektów w .NET (oprócz zmiany interfejsu w czasie wykonywania) – Philipp

+0

@PhilippMehrwald Dzięki. Powinienem był bardziej jasno mówić o "emulacji przestrzeni nazw". Ze schematem, na który czekam, próbuję uniknąć użycia window.myns.something. Nawet zmiana go w moim pliku testowym nie powiodła się. Więc muszę mieć coś jeszcze nie tak. Dzięki! –

1

Spróbuj umieścić swoją deklarację przestrzeni nazw poza wywołaniem funkcji:

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

składni istniejących wydaje się być całkowicie poprawne, ale łamanie tej linii out może pomóc dowiedzieć się, co się dzieje nie tak z zakresu zmiennej.

+0

Dzięki, spróbowałem, ale miałem takie same wyniki. Wygląda na to, że mam coś innego. Kopać w to ... –

Powiązane problemy