Jak rozprzestrzenia moduł w wielu plikach AMD?

głosy
8

Nie mogę dowiedzieć się, czy to w ogóle możliwe, aby mieć „moduł eksportu” rozłożone po drugiej stronie wielu plików.

Jeśli mam Contact.ts plików:

// file Contact.ts
export module Contacts {
   export class Contact {
      ...
   }
}

i kolejne ContactView.ts

// file ContactView.ts
export module Contacts {
   export class ContactView {
      model: Contact;  // <---  is not recognized
   }
}

Następnie TSC nie rozpoznaje klasę Kontakt. Jak widać kontaktu i ContactView deklarowane są do przebywania w tym samym module i według specyfikacji powinno działać.

Buduję kompozytową aplikację, która korzysta z require.js i wzory AMD więc muszę używać „moduł eksportu” deklarację.

Należy zrobić jakiś rodzaj „deklaracją na przodzie” lub jakiejś skomplikowanej „przywóz”?

Dzięki za porady.

EDIT: Obecnie załadować każdy moduł osobno za pośrednictwem importu, ale jeśli zauważysz, stwarza ogromne marnotrawstwo kodu i wieloma zależnościami „importowane”. Moje pytanie, czy istnieje sposób, aby korzystać z tej samej przestrzeni nazw (tj Kontakty) aby poznać TS, że nie mam na myśli importować. Szukałem do normalnego polecenia //, ale to nie działa. Próbowałem nawet Gwiazdka * .d.ts plików deklaracji bez powodzenia tej pory.

Utwórz 08/10/2012 o 23:18
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
6

Spec pozwala na definiowanie wewnętrznych modułów w wielu plikach (w istocie, moduły wewnętrzne odnoszą się do modułu javascript wzór). Zewnętrzne moduły, takie jak AMD lub CommonJS modułów, praca na założeniu, że każdy plik jest rzeczywista „moduł kodu”, a Przestrzenie nazw / nazywając w nim nie ma znaczenia, ponieważ moduł zostanie załadowany do własnego nowego obiektu w każdym razie.

Można napisać następujący kod załadować moduł Contact.ts wewnątrz modułu ContactView.ts:

// file ContactView.ts    
import mod = module("./Contact");

export module Contacts {
   export class ContactView {
      model: mod.Contacts.Contact;  // <---  will be recognized
   }
}

I to powinno działać na tyle dobrze, ale jeśli chcesz mieć dostęp do zawartości obu modułów w innej dziedzinie (aby na przykład dokonać nowego modelu Kontakt siebie), trzeba by zasadniczo importować zarówno z nich:

import c = module("./Contact");
import cv = module("./ContactView");

Co moim zdaniem jest w porządku, wystarczy, ponieważ jesteś wyraźnie podając swoje zależności. Minusem jest to, że przyzwyczajenie mają wspólny obiekt nadrzędny, więc po nich zarówno być w „Kontakt” module-wzór prawdopodobnie nie jest bardzo przydatne.

Inną opcją jest do eksportu „Kontakt” wraz z „ContactView”, w następujący sposób (przyznano ten kod jest trochę głupie, bo jesteś już robi dokładnie to za pośrednictwem właściwości modelu ContactView, ale nigdy nie mniej ...):

export module Contacts {
   export class ContactView {
       model: mod.Contacts.Contact;
       constructor() {
           this.model = new mod.Contacts.Contact();
       }
    }

    export var Contact = mod.Contacts.Contact;
}

Więc byłbyś w stanie uzyskać do niego dostęp po załadowaniu ContactView.

EDIT: Przy okazji, nie są ograniczone tylko do wywozu modułów za pośrednictwem „modułu eksportu Name {...}”, można wyeksportować jako plik niczego sama jest moduł. Więc można mieć plik, który ma tylko „funkcja eksportu foo () {...}” bez jakiegokolwiek kodu module-wzór otoczenie go.

EDIT2: Wygląda na to AMD może mieć funkcjonalność ładowania wiele zależności i konstruowania „moduły” od tych, ale nie mam pojęcia, jak to będzie działać w TS, tu jest link, który przechodzi nad tym: http://www.adobe.com /devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html (moduły konstruktora).

Odpowiedział 09/10/2012 o 02:21
źródło użytkownik

głosy
4

Walczyłem z tym samym pytaniem na chwilę i po prostu chciałem podzielić to, co robię w przypadku ktoś wędruje w poprzek tej kwestii.

Po pierwsze, zdefiniowane sobie plik referencyjny, który deklaruje wszystkie pliki w moim module:

/// <reference path="_contacts.dependencies.ts" />
/// <reference path="../contacts/Contact.ts" />
/// <reference path="../contacts/ContactView.ts" />
/// <reference path="../contacts/ContactModel.ts" />

Należy zauważyć, że ścieżki podano w pliku są względem położenia samej (pliku odniesienia _contacts.ts), w przeciwieństwie do .jspliku odniesienia. Moja struktura katalogów wygląda następująco:

modules
    references // all of the reference files
        knockout 
        underscore
        // ... a subfolder for every 3rd party library used
    contacts
    commerce 
    // ... other modules at same level as contacts

Powrót do referencyjny nadany się. Pierwszy wiersz zawiera oddzielny plik referencyjny listę wszystkich bibliotek zewnętrznych wykorzystywanych przez moduł, takich jak podkreślenie, chwilę lub innej istniejącej biblioteki masz .d.tsplik definicja. Pozostałe linie są pliki, które tworzą moduł.

Wewnątrz każdego pliku, który jest częścią modułu, odwołać wyżej pliku:

/// <reference path="../references/_contacts.ts" />
module Contacts {
    export class Contact { 
        public model: ContactModel;
        // ...
    }
} 

Podobnie, można utworzyć pojedynczy plik odniesienie do wykazu wszystkich modułów:

/// <reference path="_address.ts" />
/// <reference path="_contacts.ts" />
/// <reference path="_commerce.ts" />

I po prostu wskazać na to z plików źródłowych.

To nie rozwiąże problemu emitowanego kodu będącego w oddzielnych plikach, choć. Do tego problemu Używam narzędzie minifikacji JavaScript, która jest zdolna do zwijania się wielu plików w jednym pliku źródłowym. W zależności od ustawień kompilacji i potrzeb przypadków użycia, może trzeba zastosować jakiś owijkę wokół wygenerowanego kodu na to, aby pracować jako moduł AMD (nie zbyt dobrze tej części jeszcze).

Odpowiedział 13/12/2012 o 00:12
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more