page navigationend change angular2 typescript

typescript - navigationend - router events subscribe angular 4



Módulo vs Espacio de nombres-Importar vs Requerir mecanografiado (4)

  1. el módulo es para paquetes externos 2. el espacio de nombres es para paquetes internos

En realidad, la palabra clave del module ha sido reemplazada por la palabra clave del namespace .

Una mejor afirmación es que los módulos son lo que solían llamarse módulos externos, el espacio de nombres es lo que solían llamarse módulos internos.

Más

Espero que esto ayude más: https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

Tengo mucha confusión con el module/namespace/export e import, require, reference uso de import, require, reference . Siendo de fondo Java, ¿alguien puede explicarme en pocas palabras cuándo usar qué y cuál es el diseño correcto? Siento que me estoy equivocando cuando estoy escribiendo un proyecto de muestra

Hasta ahora, según tengo entendido 1. el module es para paquetes externos 2. el namespace es para paquetes internos

  • ¿No entendí cómo los categorizamos?
  • ¿Cuándo exportar una clase o espacio de nombres o paquete?
  • Si exportamos paquete / espacio de nombres, todas las clases dentro de eso se exportan o necesitan exportarse explícitamente
  • ¿Cómo se puede importar / requerir cada uno de ellos?

Según el documento , si estoy creando cada archivo "ts" para cada administrador / modelo, ¿Tipos de letra no recomienda usar "espacios de nombres"? ¿Usar directamente rutas de referencia?

Por favor explique en detalle ya que vengo de diferentes antecedentes y no estoy seguro acerca de ES6 / ES5, etc.

He visto a varias personas plantearse / confundirse con las mismas preguntas. Espero que alguien pueda explicar en detalle el escenario del mundo real.


" require " e " import " son equivalentes en funcionalidad. podemos usarlos indistintamente porque tenemos transpiladores que realmente no les importa si el navegador los admite de forma nativa o no. pero, aunque " require " tiene sus raíces en el viejo estilo de codificación que proviene de CommonJS en 2009, "import" deriva su sintaxis de la sintaxis ES6 (ES2015) ampliamente aceptada. por lo tanto, debe usar " importar " para nuevos proyectos y no " requerir ".


Hay dos cosas:

  • Un módulo en TypeScript es una noción estándar de ES6, utiliza palabras clave de import / export en el nivel superior del código;
  • Un espacio de nombres es una noción específica de TypeScript para ayudar a organizar el código de manera obsoleta.

Espacios de nombres

Es casi una noción obsoleta. Antes de los módulos ES6, la forma común de separar el código JavaScript en un navegador era crear variables globales. Por ejemplo, todas las funciones de una API como el subrayado se ubicaron en una variable global llamada _ .

Esta antigua forma de proceder es como paquetes Java o espacios de nombres PHP. No está adaptado a la web. El nuevo estándar ECMAScript resuelve problemas como: ¿cómo usar dos bibliotecas que tienen el mismo nombre? ¿Cómo usar dos versiones distintas de la misma biblioteca?

Aviso: en las versiones de TypeScript anteriores a la definición de ECMAScript de "módulos" (verano de 2014), los espacios de nombres se denominaban "módulos internos" y los módulos se denominaban "módulos externos".

Aviso 2: La export palabras clave dentro de un namespace es un uso no estándar de TypeScript de la palabra clave. Es el medio para declarar una cosa que sea públicamente accesible desde fuera del espacio de nombres.

Módulos ES6

Un módulo es un archivo que contiene palabras clave import o export en el nivel superior del código.

TypeScript sigue el estándar de ECMAScript. Sugiero leer una buena introducción a los módulos ES6 en un artículo de Mozilla.

Si desea usar módulos en una aplicación front-end (en un navegador), deberá usar un paquete ( Webpack [ la documentación aquí ], Browserify) o un cargador ( SystemJS [ un tutorial aquí ], RequireJS) y configurar TypeScript con este entorno.

Si su código se ejecuta en Node.js, simplemente configure el compilador TypeScript para generar el formato CommonJS.

Aviso: se puede declarar un espacio de nombres en un módulo. En ese caso, no será accesible como una variable global desde fuera del módulo. Sin embargo, se puede exportar desde el módulo.


¿No entendí cómo los categorizamos?

Los espacios de nombres se utilizan para organizar / encapsular su código. Los módulos externos se utilizan para organizar / encapsular su código Y para ubicar su código en tiempo de ejecución. En la práctica, tiene dos opciones en tiempo de ejecución: 1) combinar todo el código transpilado en un archivo, o 2) usar módulos externos y tener múltiples archivos y requerir algún otro mecanismo para acceder a esos archivos.

¿Cuándo exportar una clase o espacio de nombres o paquete?

Para hacer que un tipo o valor sea visible fuera del archivo en el que se encuentra, debe exportarlo si está dentro de un espacio de nombres. Si lo exporta al nivel superior o dentro de un espacio de nombres decidirá si ahora está en un módulo externo.

Si exportamos paquete / espacio de nombres, todas las clases dentro de eso se exportan o necesitan exportarse explícitamente

Las clases en un espacio de nombres siempre deberán exportarse explícitamente para que la clase sea visible en tiempo de compilación fuera del archivo en el que se define.

¿Cómo se puede importar / requerir cada uno de ellos?

Esto depende de si está utilizando módulos externos. Siempre será necesario importar un módulo externo para "usarlo". Importar un espacio de nombres que no está en un módulo externo es realmente solo proporcionar un alias para el espacio de nombres: aún debe prefijar el tipo / lo que sea con el alias (y es por eso que generalmente no desea usar espacios de nombres con módulos externos; hacerlo significa que siempre debe usar un prefijo al hacer referencia a cualquier cosa proporcionada por el módulo externo.) Los espacios de nombres que no están en un módulo externo pueden abarcar archivos, por lo que si está en el mismo espacio de nombres puede hacer referencia a cualquier cosa exportada por el espacio de nombres sin necesidad de ningún tipo de importación.

Para comprender realmente lo anterior, necesita algunos conocimientos básicos. La clave para entender con referencias / espacios de nombres / módulos externos es lo que hacen estas construcciones en tiempo de compilación y lo que hacen en tiempo de ejecución.

Las directivas de referencia se utilizan en tiempo de compilación para localizar información de tipo. Su fuente tiene un símbolo particular en ella. ¿Cómo ubica el compilador TypeScript la definición de ese símbolo? La directiva de referencia ha sido subsumida en gran medida por el mecanismo tsconfig.json: al usar tsconfig.json, le dice al compilador dónde están todas sus fuentes.

Los espacios de nombres pueden contener definiciones de tipo y / o implementación. Si un espacio de nombres contiene solo información de tipo, entonces no tiene ninguna manifestación de tiempo de ejecución en absoluto; puede verificar esto mirando la salida JS y encontrando un archivo JS vacío. Si un espacio de nombres tiene un código de implementación, entonces el código está envuelto dentro de un cierre que se asigna a una variable global con el mismo nombre que el espacio de nombres. Con espacios de nombres anidados, habrá una variable global para el espacio de nombres raíz. Nuevamente, verifique la salida JS. Los espacios de nombres son históricamente cómo las bibliotecas JS del lado del cliente han intentado evitar el problema de las colisiones de nombres. La idea es envolver toda su biblioteca en un cierre y luego exponer una huella global tan pequeña como sea posible, solo una variable global que haga referencia al cierre. Bueno, el problema sigue siendo que has reclamado un nombre en el espacio global. ¿Y si quisieras, digamos, dos versiones de una biblioteca? Un espacio de nombres TypeScript todavía tiene el problema de cómo ubicar la fuente para el espacio de nombres. Es decir, el código fuente que hace referencia a AB todavía tiene el problema de decirle al compilador cómo ubicar AB, ya sea usando directivas de referencia o usando tsconfig.json. O colocando el espacio de nombres en un módulo externo y luego importando el módulo externo.

Los módulos externos se originaron con JS del lado del servidor. Existe una correspondencia uno a uno entre un módulo externo y un archivo en el sistema de archivos. Puede usar la estructura de directorios del sistema de archivos para organizar módulos externos en una estructura anidada. La importación de un módulo externo generalmente siempre introducirá una dependencia de tiempo de ejecución en ese módulo externo (la excepción es cuando importa un módulo externo pero luego no usa ninguna de sus exportaciones en la posición de valor, es decir, solo importa el módulo externo para llegar a su tipo de información). Un módulo externo está implícitamente en un cierre, y esta es la clave: el usuario del módulo puede asignar el cierre a cualquier variable local que desee. TypeScript / ES6 agrega una sintaxis adicional en torno a la asignación de las exportaciones de los módulos externos a los nombres locales, pero esto es simplemente un detalle. En el lado del servidor, localizar un módulo externo es relativamente sencillo: simplemente ubique el archivo que representa el módulo externo en el sistema de archivos local. Si desea utilizar módulos externos en el lado del cliente, en un navegador, se vuelve más complejo ya que no hay un equivalente al sistema de archivos que tiene el módulo disponible para cargar. Entonces, en el lado del cliente, necesita una forma de agrupar todos esos archivos en un formulario que se pueda usar de forma remota en el navegador; aquí es donde los paquetes de módulos como Webpack (Webpack hace mucho más que los módulos de paquete) y Browserify entra en juego. Los paquetes de módulos permiten la resolución de tiempo de ejecución de sus módulos externos en el navegador.

Escenario del mundo real: AngularJS. Imagina que los módulos externos no existen, usa un solo espacio de nombres para limitar la contaminación del espacio global (en el ejemplo a continuación, una sola variable MyApp es todo lo que está en el espacio global), exporta solo interfaces y usa la inyección de dependencia AngularJS para hacer implementaciones Disponible para su uso. Coloque todas las clases en una raíz de directorio, agregue un tsconfig.json a la raíz, instale tipings angularjs en la misma raíz de directorio para que tsconfig.json también lo recoja, combine toda la salida en un archivo JS. Esto funcionará bien para la mayoría de los proyectos si la reutilización de código no es una gran preocupación.

MyService.ts:

namespace MyApp { // without an export the interface is not visible outside of MyService.ts export interface MyService { .... } // class is not exported; AngularJS DI will wire up the implementation class MyServiceImpl implements MyService { } angular.module("MyApp").service("myService", MyServiceImpl); }

MyController.ts:

namespace MyApp { class MyController { // No import of MyService is needed as we are spanning // one namespace with multiple files. // MyService is only used at compile time for type checking. // AngularJS DI is done on the name of the variable. constructor(private myService: MyService) { } } angular.module("MyApp").controller("myController", MyController); }

Usar IIFE para evitar contaminar el alcance global del tiempo de ejecución. En este ejemplo, no se crean variables globales en absoluto. (Se supone un tsconfig.json).

Foo.ts:

namespace Foo { // without an export IFoo is not visible. No JS is generated here // as we are only defining a type. export interface IFoo { x: string; } } interface ITopLevel { z: string; } (function(){ // export required above to make IFoo visible as we are not in the Foo namespace class Foo1 implements Foo.IFoo { x: string = "abc"; } // do something with Foo1 like register it with a DI system })();

Bar.ts:

// alias import; no external module created import IFoo = Foo.IFoo; (function() { // Namespace Foo is always visible as it was defined at // top level (outside of any other namespace). class Bar1 implements Foo.IFoo { x: string; } // equivalent to above class Bar2 implements IFoo { x: string; } // IToplevel is visible here for the same reason namespace Foo is visible class MyToplevel implements ITopLevel { z: string; } })();

Usando IIFE puede eliminar la introducción de MyApp como una variable global en el primer ejemplo.

MyService.ts:

interface MyService { .... } (function() { class MyServiceImpl implements MyService { } angular.module("MyApp").service("myService", MyServiceImpl); })();

MyController.ts:

(function() { class MyController { constructor(private myService: MyService) { } } angular.module("MyApp").controller("myController", MyController); })();