Hvordan spre modul på tvers av flere AMD-filer?

stemmer
8

Jeg kan ikke finne ut om det også mulig å ha en eksport modul spre tvers av flere filer.

Hvis jeg har fil Contact.ts:

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

og en annen ContactView.ts

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

Da TSC ikke gjenkjenner Kontakt klasse. Som du kan se kontakt og ContactView er erklært å oppholde seg i samme modul og i henhold til spesifikasjonen det skal fungere.

Jeg bygger et sammensatt program som bruker require.js og AMD mønstre så jeg må bruke eksport modul erklæring.

Bør jeg gjøre noen form for foran erklæring eller noen vanskelige import?

Takk for råd.

EDIT: Foreløpig jeg laste hver modul separat via import, men hvis du vil legge merke til, det skaper en enorm sløsing med kode og masse import avhengigheter. Mitt spørsmål var om det er en måte å bruke samme navnerom (dvs. Kontakter) for å gi beskjed til TS at jeg mener ikke å importere. Jeg var ute i den normale // kommando, men det fungerer ikke. Jeg prøvde * .d.ts erklæringen filer uten å lykkes så langt.

Publisert på 08/10/2012 klokken 22:18
kilden bruker
På andre språk...                            


2 svar

stemmer
6

Spec lar deg definere interne moduler på tvers av flere filer (i hovedsak interne moduler referere til javascript-modulen mønster). Eksterne moduler, for eksempel AMD eller CommonJS moduler, arbeid på ideen om at hver fil er selve "modul med kode", og navne / navngi innenfor det er irrelevant ettersom modulen vil bli lastet inn i sin egen nye objekt uansett.

Du kan skrive følgende kode for å laste Contact.ts modulen innsiden av ContactView.ts modulen:

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

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

Og det skal fungere godt nok, men hvis du ønsker å ha tilgang til innholdet i begge modulene i et annet område (til for eksempel lage en ny kontakt modell selv), ville du må i hovedsak importere dem begge:

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

Som jeg tror er greit nok, fordi du sier klart dine avhengigheter. Ulempen er at de ikke vil dele en felles overordnede objektet, så har dem begge være i en "Kontakt" modul-mønster sannsynligvis ikke er av stor bruk.

Et annet alternativ er å eksportere "Kontakt" sammen med "ContactView", som følger (gitt denne koden er litt dumt fordi du allerede gjør akkurat det via modellen tilhører ContactView, men ikke desto mindre ...):

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

    export var Contact = mod.Contacts.Contact;
}

Så du ville være i stand til å få tilgang til det etter å ha lastet ContactView.

EDIT: Forresten, er du ikke begrenset til bare eksport moduler via "eksport modul Name {...}", kan du eksportere noe som selve filen er modulen. Så du kan ha en fil som bare har "eksport funksjon foo () {...}" uten noen modul-mønster kode pakke det.

EDIT2: Det ser ut som AMD kan ha funksjonalitet for å laste flere avhengigheter og konstruere "moduler" fra dem, men jeg har ingen anelse om hvordan det ville fungere i TS, her er en link som går over at: http://www.adobe.com /devnet/html5/articles/javascript-architecture-requirejs-dependency-management.html (Constructors moduler).

Svarte 09/10/2012 kl. 01:21
kilden bruker

stemmer
4

Jeg slet med det samme spørsmålet for en stund, og ville bare dele det jeg gjør i tilfelle noen andre vandrer over dette spørsmålet.

Først definerte jeg meg selv en referanse fil som erklærer alle filene i min modul:

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

Legg merke til at banene er angitt i filen står i forhold til plasseringen av referansefilen ( _contacts.ts), i motsetning til en .jsreferansefilen. Min katalogstruktur ser slik ut:

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

Tilbake til referansefilen selv. Den første linje inneholder en separat referanse fil liste over de eksterne biblioteker som brukes av modulen, som understrekning, øyeblikk eller annet eksisterende bibliotek man har en .d.tsdefinisjon fil for. De øvrige linjene er de filene som utgjør modulen.

Inni hver fil som er en del av modulen, jeg referere til filen ovenfor:

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

På samme måte kan du lage en eneste referanse fil å liste alle dine moduler:

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

Og bare peke til denne fra kildefilene.

Dette løser ikke problemet med den utsendte kode er i separate filer, skjønt. For det problemet jeg bruker en Javascript minifisering verktøyet, som er i stand til bunting opp flere filer til en enkelt kilde fil. Avhengig av samle innstillinger og bruk case behov, må du kanskje bruke noen wrapper rundt den genererte koden for at det skal fungere som en AMD-modul (ikke altfor kjent med at en del ennå).

Svarte 12/12/2012 kl. 23:12
kilden bruker

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