javascript - Hur man initierar - AngularJs-app med TypeScript


Jag har följande AngularJS-app skriven med TypeScript

Huvudappen där jag initierar appen:

module MainApp {
   export class App {
      public static Module : ng.IModule = angular.module("mainApp", [])
   }
}

Och min kontroller

module MainApp {
   export class Person {
     public firstName: string;
     public lastName: string;
   }

   export  interface IMainAppCtrl {

   }

   export class MainAppCtrl implements IMainAppCtrl {
      public person : Person;
      constructor() {
          this.person = new Person();
          this.person.firstName = "Vorname";
          this.person.lastName = "Nachname";
      }
  }

  MainApp.App.Module.controller("mainAppCtrl", MainAppCtrl);
}

Det fungerar, men jag är inte särskilt nöjd med den här lösningen, eftersom jag här måste registrera kontrollern för min app i själva kontrollern

MainApp.App.Module.controller("mainAppCtrl", MainAppCtrl);

Det skulle vara trevligt om det fanns en möjlighet att registrera kontrollern direkt i "App"-klassen som:

public static Module : ng.IModule = angular.module("mainApp", []).controller("mainAppCtrl", MainAppCtrl);

men det fungerar inte här, jag får felmeddelandet från webbläsaren

"Argumentet 'mainAppCtrl' är inte en funktion, fick undefined"

i mina gamla vanliga JS Angular-kontrollers hade jag en mainApp där jag har registrerat alla mina kontrollers som

angular.module("app.main", [
    "ui.router",
    "ngSanitize",
    "DirectiveTestsCtrl",
    ....
]);

och i min kontroller har jag bara registrerat kontrollerens namn för Angular:

angular.module("DirectiveTestsCtrl", [])
       .controller("DirectiveTestsCtrl", function () { ... });

är detta också möjligt med de ovan visade snipparna med typescript eller vad är bästa praxis här - jag har sökt på webben och hittat många exempel men inte ett bra för controllerAs-syntax och med "module Name { class xyz }" som verkligen fungerade.

Svar #1

TLDR; - Exportera en statisk funktion i din huvudmodul som kommer hantera all uppstart-/initieringslogik. För barn-/delmoduler, exportera en statisk readonly-egenskap som gör att du kan bygga en gång och hämta flera gånger en definierad Angular-modul.

Huvudmodul

Jag har tagit ett liknande tillvägagångssätt, men det kapslar åtminstone in tillägget av komponenter (kontroller, tjänster) inom moduldefinitionen

module appName {
  export class App {
    static createModule(angular: ng.IAngularStatic) {
      angular.module('moduleName', ['ngRoute'])
          .controller('refCtrl', ReferencedControllerClass)
          .service('dataService', DataService);
    }
  }
}

appName.App.createModule(angular);

Underordnade moduler

Sedan i andra interna moduler skapar jag en statisk referens till modulen för att ta hänsyn till att den refereras mer än en gång...

module appName {
  export class SubModuleName {
    private static _module:ng.IModule;

    public static get module():ng.IModule {
      if (this._module) {
        return this._module;
      }

      this._module = angular.module('subModuleName', []);

      this._module.controller('SomeCtrl', SomeController);

      return this._module;
    }
  }
}

Med detta tillvägagångssätt kan jag injicera min SubModule i huvudmodulen för Angular via:

angular.module('moduleName', ['ngRoute', appName.SubModuleName.module.name])

Observera: Huvudmodulen kan definieras på samma sätt som barnmodulerna för konsekvens, men jag refererar/buildar den bara en gång, så jag brydde mig inte om att cache:a den med en lokal statisk instans.