Angular: NgModule en grandes proyectos

Creado en 7 ago. 2016  ·  144Comentarios  ·  Fuente: angular/angular

Estoy enviando un... (marque uno con "x")

[X] feature request / proposal

He estado leyendo sobre NgModule y quiero exponer algunos casos de uso que no estoy completamente seguro de que la propuesta actual (https://docs.google.com/document/d/1isijHlib4fnukj-UxX5X1eWdUar6UkiGKPDFlOuNy1U/pub) tenga en cuenta. .

Contexto

Soy parte de un equipo que crea un Enterprise Framework (basado en Angular 2). Este marco será luego la base para otras aplicaciones dentro del mismo ecosistema.

Hemos dividido el marco en proyectos/módulos más pequeños (piense en ellos como paquetes npm separados). Estos módulos son conjuntos de controles (que luego se reutilizan en otros módulos) o páginas que usan esos controles.

Ejemplo

Un ejemplo rápido puede ser:

Módulo de controles

import {Component} from "@angular/core";

@Component({
   selector: "my-combobox",
   ...
})
export class MyComboBox{

}

Módulo de lista de verificación
// El módulo de lista de verificación depende del módulo de controles. Los controles se tratan como un módulo de terceros.

import {Component} from "@angular/core";
import {MyComboBox} from "controlsmodule/components/mycombobox";
// Please note that we are only loading a specific component within the module, not all components inside that module.

@Component({
     selector: "my-checklist-page",
     directives: [MyComboBox, ...],
     ...
})
export class ChecklistPage{

}

Bootstrap no conoce los módulos Controls y Checklist. Se cargan de forma diferida dependiendo de la interacción del usuario. En este caso, si el usuario navega a una lista de verificación, se cargará el componente ChecklistPage y luego seguirá MyComboBox (debido a la _importación_ realizada por ChecklistPage)

El módulo de lista de verificación tiene otra docena de componentes. Cada uno depende de otra docena de componentes de múltiples módulos.

No es práctico (por no decir casi imposible) importar todos los componentes a la declaración de NgModule. Estamos hablando de varios cientos de componentes que _podrían_ usarse durante el tiempo de ejecución de la aplicación.

Además, la aplicación debe ser modular y de carga diferida cuando sea posible. Las diferentes interacciones dentro de la aplicación darán lugar a la carga de módulos completamente diferentes.

Comportamiento esperado/deseado

La solución actual, con directivas de alcance de componentes, funciona de maravilla para este caso de uso. No estoy seguro de cómo se desarrollará esto con NgModule.

Más que eso, actualmente podemos ver claramente las dependencias que necesita cada componente (en este caso ChecklistPage). Haciendo que el mantenimiento sea mucho más fácil.

Tener todos los componentes necesarios importados en un NgModule y luego usarlos indistintamente en varios componentes parece una solución fantástica para aplicaciones pequeñas. Siento que en un desarrollo a largo plazo, con varias iteraciones a lo largo de varios años, con rotación de equipos,... hacer que cada componente indique explícitamente de qué depende sin mirar la plantilla (y tener errores de compilación cuando falta algo) es una gran ventaja.

Conclusión

Por favor, hágame saber si fui claro en mi explicación. El objetivo de este número es crear conciencia sobre esta situación y obtener su opinión sobre cómo proceder.

Estamos disponibles para mostrarle nuestro trabajo actual, tenemos varios cientos de componentes Angular 2 en 8 proyectos desarrollados en el último año (desde alfa 27).

Comentario más útil

Gracias a todos por los comentarios, disculpas por haber tardado tanto en recibir una respuesta; estuvimos muy ocupados durante la última semana (migrando las aplicaciones internas de Google a NgModules, por lo que también sentimos el dolor de la refactorización)

Déjame ver si puedo aclarar algunas de las preguntas y conceptos erróneos aquí.

Lo primero que debe comprender sobre @NgModule() (y @Component y cualquier otro decorador de Angukar) es que son puramente una construcción de tiempo de compilación: existen para permitir que el compilador angular descubra un gráfico de dependencia en una aplicación.

Una versión (simplificada) de lo que hacen nuestros decoradores:

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

No cambian ni modifican el comportamiento de la clase decorada de ninguna manera, simplemente adjuntan algunos metadatos. Angular usa esos metadatos para construir su aplicación y compilar plantillas.

En el modo JiT, esto sucede "Justo a tiempo": entre la llamada a bootstrapModule y la representación de su primer componente, el compilador de Angular recupera los metadatos adjuntos a las clases mediante la API Reflect:

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

Sin embargo, en el modo AoT, esto funciona un poco diferente: en el momento de la compilación, de manera estática (es decir, sin ejecutar el código) extraemos los mismos metadatos del código fuente buscando decoradores.

Esto funciona bien cuando está arrancando un solo componente, pero hemos escuchado muchos comentarios de desarrolladores que están haciendo cosas más complejas: arrancando múltiples componentes raíz o arrancando diferentes componentes según el estado de autenticación, etc.

Entonces, si bien los decoradores de @Component nos dieron la capacidad de analizar estáticamente un Componente, no teníamos la capacidad de analizar estáticamente de manera confiable una _Aplicación_

Cosas que caen bajo el paraguas de una "aplicación"

  • PLATAFORMA_DIRECTIVAS/TUBERIAS/PROVEEDORES
  • cosas que agregaste previamente a bootstrap()
  • configuración de nivel de compilador
  • múltiples componentes raíz
  • uso del lado del servidor.

NgModules introduce la idea de un conjunto de características analizables estáticamente. Lo que es interesante es que en el modo de compilación AoT, analizamos su módulo raíz y _generamos_ una ModuleFactory para cada módulo en la aplicación; esta es la versión precompilada de un módulo, que contiene _solo_ las fábricas a las que hace referencia estáticamente en las plantillas y las que marcar como "entryComponents"

Debido a que ya extrajimos la información necesaria para la compilación antes de tiempo, en realidad podemos sacudir a los decoradores (ngc se encargará de esto automáticamente para el final), y en lugar de agrupar su aplicación comenzando en su módulo raíz, comience en su Module_Factory_ raíz generado, que solo contiene el código que realmente se usa en su aplicación, por lo que no paga una penalización por la modularidad, y las herramientas como rollup y webpack2 pueden funcionar _más_ eficientemente

más a seguir en la próxima respuesta ...

Todos 144 comentarios

No me parece que ngModules prohíba la configuración que estás buscando, ¿ya has jugado con ella? Puede tener varios módulos diferentes y hacer carga diferida, etc. http://plnkr.co/edit/NAtRQJBy50R19QAl90jg?p=info

Para algo más similar a lo que parece estar tratando de hacer, esté atento a la transición de material2: https://github.com/angular/material2/pull/950/files

Hola @qdoble ,

Gracias por la rápida respuesta.
Mirando https://github.com/jelbourn/material2/blob/ecbb4f42e0473899f6ad15d8e4ed8f262ded7a99/src/components/button-toggle/button-toggle.ts , ¿está diciendo que para lograr la misma funcionalidad que tenemos ahora, necesitamos declarar un NgModule en cada componente? (eso es lo que se agregó al final del archivo, ¿verdad?)

Además, no cubre el problema de mantenimiento que mencioné en mi declaración inicial. Tener las dependencias de cada componente/directiva declaradas en su decorador es, para mí, una gran ventaja que me gustaría conservar.

@jpsfs si quisiera crear un alcance individual para todos y cada uno de los componentes, entonces supongo que tendría que crear diferentes ngModules para cada uno. Si bien esto puede crear más código en su caso, supongo que creará menos código para la gran mayoría de otras personas al analizar mi módulo en lugar de por componente.

En cuanto al segundo problema, podría declarar el ngModule y el componente uno al lado del otro, por lo que si bien agregaría 3 o 4 líneas adicionales de código a sus archivos, no creo que cree un gran problema.

Diría que la gran mayoría de los casos de uso no requieren directivas de alcance por componente, pero en el caso de que sí, ngModules aún lo admite para algunas líneas más de código.

@qdoble Gracias.

No estoy seguro de que esta sea una situación o/o, puedo ver que ambos escenarios funcionan juntos, no es necesario eliminar la funcionalidad que ya tenemos. Si alguien quiere usar módulos, puedo verlo como una gran adición. Mientras tanto, el marco podría funcionar sin módulos (como funciona hoy). Creo que incluso el problema de la compilación fuera de línea se puede resolver con las cosas como están actualmente.

Lo dejo abierto a ver si alguien tiene algo que añadir al asunto.

@jpsfs entendió, si yo estuviera en tu situación, definitivamente preferiría que dejaran ambas opciones abiertas :)

Escribieron el motivo de la desaprobación de las directivas de componentes en el documento que publicaste, en cuanto a la creación de dos ámbitos, pensando que el ámbito de ngModule es lo suficientemente pequeño y que está más en línea con el modelo ES6.

Un miembro del equipo también mencionó antes que generalmente es problemático tener dos formas diferentes de hacer las cosas... y a largo plazo, podría ver el problema aquí... si tiene algunos proyectos donde las personas usan ngModules y otros proyectos donde no los hay, eso crea más problemas de mantenimiento, capacitación y compatibilidad.

Nunca se sabe en qué dirección irá este proyecto hasta que sea definitivo, así que veremos si toman en consideración lo que dices.

Incluso actualmente estoy trabajando en el diseño de la arquitectura para una gran aplicación empresarial.
A diferencia de su situación @jpsfs , estoy entusiasmado con NgModules y básicamente basé la arquitectura de mi aplicación en NgModule.

Cada módulo tendrá su propio conjunto de rutas y dependencias de componentes. Nunca podemos crear una pieza de funcionalidad con un solo componente, necesita rutas, al menos un componente inteligente y algunos componentes y servicios tontos que lo acompañen. Conecta todo esto en un Módulo y listo.

En cuanto a la carga diferida, en lugar de cargar el código para cada componente, parece bueno que cada código de NgModule se cargue a la vez, por lo que su funcionalidad se puede utilizar por completo una vez descargada.

La creación de una jerarquía de módulos también es mucho más simple y proporciona una excelente función Plug and Play de forma gratuita.

Actualmente también estamos trabajando en una aplicación con bastantes componentes (no cientos, sino docenas). No es necesario que dividamos esta aplicación en varios módulos (de carga diferida), pero ahora importamos todos esos componentes en el archivo de arranque y los pasamos a declarations alguna manera se siente mal y rompe la encapsulación del componente. . Como dijo @jpsfs , antes estaba muy claro qué componentes y directivas usaba otro componente. Así que también agradecería tener la opción:

  • Si se trata de una directiva de uso bastante común, declárela en el módulo.
  • Si es algo como TaskListItem simplemente impórtelo en TaskList .

Tal vez algún miembro central pueda brindar más información sobre la decisión de desaprobar el segundo enfoque. Habiendo trabajado con él durante varios meses, se siente bastante bien;)

Para hacer eco del punto de @choeller , se siente extraño alejarse de la capacidad de proporcionar encapsulación de componentes.

Mi preocupación específica es que ahora los nombres/selectores de los componentes se filtran en toda la aplicación, mientras que antes podías reutilizar los selectores para diferentes componentes al incluir directivas específicas según corresponda.

Ahora todos los selectores tendrían que ser únicos por componente, ¿verdad? ¿O estoy malinterpretando cómo funciona esto?

Sentí que la funcionalidad original coincidía con los beneficios similares proporcionados por la emulación CSS shadow-DOM, en el sentido de que podíamos preocuparnos menos por las colisiones de selectores, etc. en aplicaciones grandes. Esa fue una gran ventaja en mi opinión.

Mi primer pensamiento sobre ngModule fue "Oh, eso es como en angular 1". Por muy bueno que ya fuera angular 1, angular 2 es mucho mejor en muchos puntos. El mejor punto para mí fue que los Componentes crean algún tipo de árbol de dependencia. Tengo un componente principal con un enrutador que define varios puntos de entrada con su propio componente. Y cada componente sabe lo que necesita, no hay razón para que el componente principal sepa lo que necesita cualquiera de los componentes al final del árbol.
Ahora volvemos a los buenos viejos tiempos de angular 1, donde tenemos una definición de módulo gigante.
¿Recuerda las veces que el punto de entrada de su aplicación se veía así?

angular.module("myApp")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")

Pensé que esto pertenecía al pasado. Empecé a trabajar con ng-metadata para mejorar los proyectos antiguos de angular 1 y prepararme para la migración. Realmente me encanta el hecho de que tiene un árbol de dependencias y no una lista global de "lo que podría aparecer en esta aplicación".

Esto hace que los componentes reutilizables sean más difíciles. No entiendo cómo esto mejora las cosas al tener todo en un alcance global/módulo, creo que el equipo de ng2 ha cedido ante los usuarios de ng1 que no quieren cambios.

@DaSchTour @damiandennis Entiendo las críticas a esta arquitectura, sin embargo, referirse a ella como una especie de alcance global es inexacto, la metodología que sugieren que tome es tener módulos de funciones: https://angular.io/docs/ts /latest/guide/ngmodule.html#! #módulos-de-características

@qdouble Bueno, al final solo se trata de cambiar todos los Componentes a Módulos. Aunque esto se anuncia como un cambio para reducir el código repetitivo, introduce una gran cantidad de necesidades repetitivas.

Si bien hasta RC4 un componente para cada "página"/vista de la aplicación era suficiente, sé que tendré que crear un módulo, un componente y un enrutamiento para cada vista. Capto la intención. Pero de alguna manera tengo la impresión de que está diseñado para facilitar algunas cosas sin tener que ver con muchos otros puntos. E incluso con el patrón del módulo de funciones, tengo que reducirlos muy pequeños para evitar el infierno de la dependencia, agregando todo lo que podría ser necesario porque no puedo ver qué parte de mi aplicación necesita qué componentes.

Al final, los módulos son tan pequeños que tienen listas de dependencia repetitivas similares a los componentes actuales.

Al final, no resuelve para qué fue diseñado y solo agrega mucho trabajo. Tengo la sensación de que aquí hay cierto desajuste entre el diseño y la realidad.

los desarrolladores son perezosos/les falta tiempo y toman atajos. Esto alienta a los desarrolladores a tomar la ruta rápida de simplemente incluir todo en bootstrap. Al menos con los componentes, existe algún requisito para incluir sus dependencias. Sí, también pueden ser perezosos y crear un solo componente para toda la aplicación, pero eso sería más fácil de arreglar ya que todas las dependencias están en ese componente y no se mezclan entre el archivo de arranque y cada archivo de componente dentro de la aplicación.

@DaSchTour si todos y cada uno de los componentes necesitan su propio alcance, entonces sí, creará más repetitivo... pero asumo que el equipo de ng opina que, para la mayoría de las personas, crear un nuevo módulo para cada sección de características es suficiente y algunos componentes podrían vivir en cada espacio de características.

Ahora, obviamente, no hay una solución única para todos y tener directivas a nivel de componente puede ser más simple para algunas personas. Sin embargo, parece que muchos de los comentarios aquí implican que solo quieren que crees una aplicación con un gran árbol ngModule...

Creo que es más productivo si la crítica se basa en sus sugerencias de diseño reales en lugar de un patrón de diseño de hombre de paja que no están sugiriendo (es decir, crear una aplicación empresarial que es solo un enorme ngModule)

@qdouble el patrón de diseño es simple. Utiliza un árbol de dependencias en lugar de mover las dependencias a un ámbito de módulo global. Supongo que el punto principal es que los componentes reutilizables ahora tienen que ser módulos, incluso si son muy pequeños y tienen muy poca funcionalidad. Angular material2 es un muy buen ejemplo. Un botón es un módulo que incluye un componente. Tal vez sea un error generalizado de muchos desarrolladores, que un módulo es algo que contiene más que un simple botón. Y ahora pensemos un paso más allá. Simplemente siguiendo las ideas de este artículo https://angularjs.blogspot.com/2016/08/angular-2-rc5-ngmodules-lazy-loading.html me encuentro en el punto en que tengo muchos módulos que importe una lista de módulos de material angular2 y cada uno de estos módulos consta de un solo componente.
De hecho, esto es exactamente lo que hace angular material2.

Nadie realmente entiende el punto, por qué ahora tenemos que envolver "todos" nuestros componentes en módulos. O tal vez tengamos que ver esto como una división de declaración. Las dependencias de los componentes ahora son un módulo y la definición de los componentes es la misma que antes.

Supongo que el punto es que ngModules no es solo una buena adición para facilitar las cosas, sino que nos vemos obligados a cambiar todo. Tal vez alguien debería hacer una explicación clara de por qué no pueden coexistir ambos.

@DaSchTour bueno, sí, estoy de acuerdo en que si cada componente que crea necesita su propio módulo, entonces usar ngModules crea más repetitivo... Simplemente entiendo que el equipo no cree que la mayoría de la gente necesite ese nivel de separación para cada componente.

Me encuentro en el punto en que tengo muchos módulos que importan una lista de módulos angular material2 y cada uno de estos módulos consta de un solo componente.

Usaría módulos compartidos para esto: https://angular.io/docs/ts/latest/guide/ngmodule.html#! #módulo-compartido

Ahora, tampoco estoy muy seguro de por qué piensan que es necesario eliminar por completo la capacidad de tener un alcance de componente, pero para mí, algunas de las críticas son hacer que usar ngModules sea más difícil de lo que realmente es o hacer que el diseño parezca más descuidado de lo que realmente es.

Creo que la crítica de eliminar directivas/tuberías con alcance de componente es perfectamente válida. Sin embargo, no creo que sea necesario hacer que parezca que no hay buenos patrones de diseño para ngModules.

@qdouble Creo que nadie duda de que existen buenos patrones de diseño para ngModules. Pero por lo que entiendo, los módulos son solo un envoltorio alrededor de un conjunto de componentes, directivas y servicios para exponerlos como una unidad para la aplicación. Eso es válido y una gran idea. Pero, ¿por qué tengo que definir las dependencias (que pueden existir solo dentro del módulo) para el módulo y no para el componente?

Tomando el ejemplo de @choeller
El módulo TaskDashboard tiene las siguientes cosas

  1. Componente de lista de tareas
  2. Componente de elemento de tarea
  3. Componente de filtro de tareas
  4. Servicio de tareas

El componente Taskitem solo se necesita dentro de la Lista de tareas y la Lista de tareas depende del Componente Taskitem. Taskfilter no necesita el componente Taskitem. Ahora no tengo el elemento de tarea como una dependencia en la lista de tareas. El siguiente paso es crear un módulo TaskSearch. Agrego las siguientes cosas.

  1. Componente de lista de tareas
  2. Componente de búsqueda de tareas
  3. Servicio de tareas

Bueno, me perdí el componente Taskitem y está roto. Tasklist siempre depende de Taskitem, pero esta dependencia está oculta en el módulo. La reutilización de componentes se hace más difícil y crea una fuente adicional de errores.

De acuerdo, mientras leía más a través de la guía de módulos, encontré esta línea

Los componentes, directivas y tuberías deben pertenecer exactamente a un módulo.

Entonces, el ejemplo muestra exactamente la preocupación que se plantea aquí. No puede haber ningún componente compartido. Entonces, según mi ejemplo, tendría que dividir todo en módulos.

Mientras trabajaba en los errores extraños y no elusivos que surgen al usar ngModule, también encontré que la extensión de componentes ahora no funciona tan bien como antes. Tenía un conjunto de componentes con las dependencias necesarias que simplemente podía ampliar. Ahora tengo que encargarme de importar las dependencias en el módulo en el que incluyo mi componente extendido.

@DaSchTour en su ejemplo, Taskitem debe ser parte del Módulo de lista de tareas ... por lo que lógicamente serían dos componentes en un módulo, no uno para cada uno.

Como señaló @sirajc , un patrón de diseño típico sería tener un componente inteligente superior, seguido de componentes tontos adicionales... por lo que en una aplicación típica del mundo real, la mayoría de los módulos consistirían en unos pocos componentes (ya sea por el inteligente/tonto patrón de componente o por patrón de función relacionado), no solo un componente por módulo a menos que solo esté creando componentes de terceros o algo así.

@qdouble @DaSchTour Es cierto que la nueva arquitectura no significa necesariamente que enumere todos sus componentes en un solo archivo, pero mirando la aplicación que estamos construyendo actualmente me quedaría con esta declaración de @DaSchTour

Tengo la sensación de que aquí hay cierto desajuste entre el diseño y la realidad.

Así que tenemos bastantes componentes que representan pequeñas unidades en la página como TaskListItem que están 100% vinculados a una vista especial. Crear módulos para cada una de esas páginas sería una exageración total. En nuestro caso, hay muy pocas razones para dividir en múltiples módulos, pero muchas más razones para encapsular componentes.

tl; dr
Es genial poder definir algunas dependencias a nivel de módulo, pero es realmente triste que ya no podamos definir dependencias a nivel de componente.

@DaSchTour , el componente del botón Material2 está vinculado al módulo para que sea independiente. Aquellos que necesitan usar el botón pueden importar ButtonsModule . Además, si ve el código del Módulo, contiene dos componentes MdButton y MdAnchor , envolverlos en ButtonsModule hace que las cosas sean más fáciles de usar

Me pregunto si es posible crear algún componente híbrido/objeto de módulo que fusione los dos conceptos en uno para evitar la duplicación de archivos. Esencialmente, poder declarar un componente como módulo una vez y luego importarlo como módulo, según sea necesario. Honraría el enfoque actual, pero minimizaría el modelo estándar.

@choeller Estoy de acuerdo en que tener módulos es una buena adición, eliminar dependencias a nivel de componente, sin embargo, parece incorrecto.

Complementando lo que otros escribieron anteriormente, creo que la idea central aquí no es experimentar la miseria de un proyecto enorme con un módulo enorme con cientos de componentes. Más bien, es construir una aplicación a partir de una cantidad razonable de NgModules de tamaño mediano. Lo suficientemente grandes como para que no sean triviales, lo suficientemente pequeños como para que no tengas una gran cantidad de ellos; dividido a lo largo de líneas de falla que tenderían a facilitar la reutilización y la modularidad en el sentido antiguo de la informática de alta cohesión y bajo acoplamiento.

Al hacerlo, los módulos deberían convertirse en un concepto bastante útil para que jueguen en proyectos grandes.

Eso está muy bien resumido @kylecordes. NgModules ayuda en la buena composición de la aplicación. Pequeños módulos reutilizables componen toda la aplicación.
Otro beneficio incluye la disponibilidad ambiental de directivas. Anteriormente solíamos agregar ROUTER_DIRECTIVES en toda la aplicación. Ahora RouterModule.forRoot() hace eso por nosotros.
BrowserModule, CommonModule, FormsModule tiene más sentido que incluir directivas a través de cada componente.

MaterialModule, por otro lado, proporciona todo y, si necesita un control más preciso, ButtonsModule, etc., nos ayudará.
Esa es la belleza de la composición. Acéptalo y crea tu sinfonía

Además de esto está LazyLoading. Si no fuera por NgModules, ¿cómo se puede definir el número de componentes y servicios que deben ir juntos para crear una unidad enrutable? No puede descargar archivos sueltos, ya que esto generará una gran cantidad de solicitudes de red. De lo contrario, debe crear un paquete donde enumere todos los archivos dependientes para crear un paquete. NgModule hace esto con una sintaxis intuitiva.

@kylecordes

Complementando lo que otros escribieron anteriormente, creo que la idea central aquí no es experimentar la miseria de un proyecto enorme con un módulo enorme con cientos de componentes. Más bien, es construir una aplicación a partir de una cantidad razonable de NgModules de tamaño mediano. Lo suficientemente grandes como para que no sean triviales, lo suficientemente pequeños como para que no tengas una gran cantidad de ellos; dividido a lo largo de líneas de falla que tenderían a facilitar la reutilización y la modularidad en el sentido antiguo de la informática de alta cohesión y bajo acoplamiento.

¿No serían esas líneas de falla muy diferentes para los desarrolladores de aplicaciones frente a los desarrolladores de bibliotecas? Los desarrolladores de bibliotecas deberían ser una minoría, pero esa parece ser la principal queja. Al construir un marco reutilizable, el objetivo de querer minimizar el tamaño del módulo genera mucho ruido adicional.

@sirajc

Además de esto está LazyLoading. Si no fuera por NgModules, ¿cómo se puede definir el número de componentes y servicios que deben ir juntos para crear una unidad enrutable? No puede descargar archivos sueltos, ya que esto generará una gran cantidad de solicitudes de red. De lo contrario, debe crear un paquete donde enumere todos los archivos dependientes para crear un paquete. NgModule hace esto con una sintaxis intuitiva.

Pude hacer esto fácilmente con el antiguo enrutador simplemente usando un componente que funcionaba como un contenedor para una sección de mi aplicación. Este módulo trajo solo los componentes directos que necesitaba, lo que traería sus propias dependencias. Cualquier cargador de módulos decente podría cargar la cadena de dependencia (a través de importaciones) de ese componente sin incluir todas las subdependencias en el componente de nivel superior. Lo mismo ocurre con los empaquetadores que deberían usar algún tipo de lógica de resolución de módulos. En resumen: no hay ninguna razón, desde una perspectiva de carga diferida, por la que un desarrollador deba declarar todas las dependencias contenidas en el componente de nivel superior.

Realmente parece que ngModule es una solución en busca de un problema...

Hay algo que decir acerca de poder abrir cualquier componente dado, echar un vistazo a su matriz de directivas y saber exactamente de qué componentes/directivas depende. ¿Es más detallado tener que importar un componente de botón entre los numerosos componentes que lo usan? Sí, pero prefiero tener un repetitivo adicional y hacer que las cosas sean explícitas e inmediatamente escaneables que buscar en el árbol de componentes/módulos para ver cómo diablos el componente Y está usando el componente X en su plantilla sin siquiera importarlo.

El argumento que se hizo anteriormente es que si alguien desea mantener los componentes aislados entre sí, podría decirse que podría crear un módulo para cada componente, pero en ese momento está escribiendo aún más repetitivo que el componente original.

Obviamente, hay otros beneficios de ngModule que no he cubierto, y aunque hay beneficios de poder agrupar secciones de una aplicación en módulos de funciones, realmente se siente como un paso atrás en lo que respecta a la claridad y tener componentes encapsulados. código que no filtra el alcance por todas partes.

Parte de la "venta dura" que el equipo de ng2 tuvo que hacer a la comunidad desde ng1 fue "sí, tendrá que importar y declarar sus directivas para cada componente, pero confíe en nosotros, apreciará ser más explícito a medida que crece su aplicación". Creo firmemente en sufrir un poco de repetición por el bien de la legibilidad y la capacidad de escaneado en un entorno de equipo a gran escala donde un miembro del equipo solo puede estar trabajando en un subconjunto muy pequeño de componentes en un momento dado.

Por lo menos, no veo ninguna razón por la que ngModule y la propiedad de directivas/tuberías no puedan coexistir. La alternativa es que cada componente en cada aplicación escrita para ng2, hasta RC5, ahora usa código obsoleto que necesita ser refactorizado de manera no trivial. Estos no son realmente el tipo de cambios que esperaría tan tarde en el desarrollo... honestamente, es bastante desconcertante.

ngModules esencialmente requiere una reescritura de la mayoría de las aplicaciones si se van a estructurar correctamente... pero el error más grande es que están forzando un nivel de alcance particular cuando la realidad es que sus módulos pueden ser tan grandes o tan pequeños como usted quiera. ser.

Si es absolutamente necesario crear un nuevo módulo para cada componente, resulta en más repetitivo = válido.

La mayoría de las aplicaciones deberían requerir que cree un módulo para cada componente individual = no válido (especialmente si está utilizando patrones de componentes inteligentes/tontos y patrones de características)

Por primera vez hoy, sentí la fatiga del lado del cliente/JavaScript que varios colegas me han transmitido. He perdido innumerables horas en los últimos días tratando de refactorizar nuestra aplicación RC4 para usar los nuevos módulos RC5.

Definitivamente estoy de acuerdo con varios sentimientos en este hilo, particularmente acerca de dar a los desarrolladores una opción en términos de la forma en que desean estructurar las dependencias de sus componentes. No me gusta que un ngModule más grande diluya el gráfico de dependencia claro entre los componentes y que los ngModules más pequeños agreguen código repetitivo adicional a cada componente. Al analizar un módulo, todo lo que sé es que al menos uno de los componentes a los que se hace referencia necesita cosas de las importaciones del módulo o declaraciones de hermanos. Si divido un módulo en varios otros módulos, básicamente me quedo con prueba y error para determinar qué dependencias requieren los nuevos módulos (la inspección cuidadosa de la plantilla del componente ayuda, de alguna manera).

Finalmente, si "olvido" exportar componentes, mi componente simplemente no se procesa, no se dan errores. Es fácil de encontrar si tiene un gráfico de módulo muy plano, ¡casi imposible cuando tiene varios niveles!

En esta etapa estoy abatido, decepcionado y descorazonado. Reuní a un equipo de desarrolladores y partes interesadas comerciales con una tecnología que ahora no sé si puedo llevar adelante. Realmente espero que se pueda encontrar un mejor equilibrio.

En esta etapa estoy abatido, decepcionado y descorazonado. Reuní a un equipo de desarrolladores y partes interesadas comerciales con una tecnología que ahora no sé si puedo llevar adelante. Realmente espero que se pueda encontrar un mejor equilibrio.

Supongo que el punto aquí es que hay una gran cantidad de desarrolladores esperando que esta tecnología esté lista para la producción y, aunque se llama Release Candidate, cada nuevo candidato trae cambios importantes y se siente más como un alfa.

Estoy seguro de que muchos equipos han pasado horas en la arquitectura de sus nuevas aplicaciones y ahora todo es una locura.

¿Cuál será el próximo cambio radical? Ni siquiera puedo imaginarlo, pero me temo que alguien encontrará la manera de introducir el próximo cambio de última hora.

De la publicación del blog RC5:

Sin embargo, si ha escrito algún código de Angular 2, probablemente se haya preguntado "¿pero POR QUÉ tengo que enumerar todas estas cosas?" - especialmente si ha notado que ciertas directivas y canalizaciones en Angular 2 son "especiales" - están disponibles para toda su aplicación sin que usted haga nada (*ngFor / *ngIf / *ngSwitch, por ejemplo).

Personalmente, no he visto esa pregunta formulada por nadie en mucho tiempo. Hasta RC5, el equipo de Angular, los recursos de aprendizaje en línea, los libros, etc., dejaron bastante claro por qué se necesitan esas declaraciones, y parece que todos aceptaron (y algunos abrazaron) ese hecho hace mucho tiempo.

En cuanto a las preguntas sobre por qué algunas son "especiales" y no es necesario declararlas, no creo que nadie argumente en contra de que haya una lista de directivas críticas de "bajo nivel" que son tan ubicuas que justifican ser "bendecidas". como disponible globalmente por el titular de la plataforma (equipo Angular).

Si el código ya está presente para manejar la elevación de las directivas en un solo ngModule, y ese código funciona invisible para el usuario final, ¿cuál es el daño en permitir ambos enfoques? Esa es una pregunta genuina, ya que es posible que no esté al tanto de algunas de las complejidades en torno a lo que podría suceder si un desarrollador mezcla y combina el enfoque. Hay muchas otras "opciones divididas" en Angular 2: formularios basados ​​​​en modelos versus plantillas, 3 opciones de idioma diferentes, decoradores de entrada/salida/host versus enfoque de propiedad: ¿cuál es el daño en otro en este punto?

Podría continuar, pero el punto que estoy tratando de hacer es que el equipo y la comunidad de Angular han invertido bastante tiempo para recalcar el mensaje de que ser más explícito es algo _bueno_, solo para lanzarse en picado, en _lanzamiento candidato 5_ de todos los tiempos, para presentarnos una solución que no ha sido un problema durante bastante tiempo.

¿Alguien del equipo tiene ganas de participar? No quiero que esto se convierta en una cámara de eco; me encantaría escuchar el otro lado del argumento. Parece que algo tan grande salió de la nada sin tener en cuenta cosas como las herramientas, la capacitación o lo cerca que aparentemente estamos del lanzamiento final.

Esta discusión planteó un problema muy grande para muchos desarrolladores que querían comenzar a desarrollar temprano con el muy esperado angular 2: cambios importantes. Hice un montón de pruebas de concepto basadas en angular 2 desde beta 17 e hice que importantes empresas y organizaciones lo adoptaran. No me arrepiento, pero tampoco estoy seguro de haberlo hecho bien. Algunos de los proyectos más recientes fueron POC y la batalla fue contra Vue.js. Angular 2 claramente ganó esa pelea sin dudas. Pero hoy, con toda la reescritura de código, los cambios de última hora, el lanzamiento no-realmente-RC, la gente comienza a perseguirme y se vuelve bastante serio. No hubiera sido el caso si ofreciera un desarrollo de Vue o React y eso es muy frustrante debido al descrédito que Angular 2 puede causar a las personas.

Me parece que no comparto la misma definición de Release Candidate que el Equipo Angular.

En cuanto al tema, NgModule, co-firmo totalmente a @jpsfs , si tiene que enumerar todos los componentes y microcomponentes dentro de la declaración de su módulo, es mejor que tenga una función prune en alguna parte o para ser el rey de la modelización porque puede ser todopoderoso, es demasiado sensible para proyectos a gran escala...

Creo que este mayor nivel adicional de modularidad era casi inevitable; y que varios marcos en competencia eventualmente terminarán con algo análogo.

Sin embargo, me pregunto si era realmente necesario hacer que este nuevo sistema de módulos de granularidad gruesa fuera completamente ortogonal al sistema de módulos subyacente, o si hubiera sido posible hacer que cada directorio de nivel superior y todos los módulos Es6 contenidos en él fueran implícitamente comprenden un NgModule de grano grueso. Quizás se podría agregar un mecanismo impulsado por una convención de este tipo además del mecanismo actual y, por lo tanto, eliminar el modelo estándar de NgModule para los proyectos que deseen seguir dicha convención.

(Por supuesto, también comparto la frustración con otros aquí, de cambios tan significativos en la etapa "RC"... Sin embargo, estoy seguro de que el equipo central también, si tuvieran que hacerlo todo de nuevo, habrían atacado a alto nivel modularidad y las fuerzas que la impulsan (carga diferida, precompilación) mucho más cerca del comienzo del proyecto en lugar de en la etapa candidata de lanzamiento. Sin embargo, así es la vida, siempre es fácil mirar hacia atrás y pensar "bueno, si había sabido entonces lo que sabemos ahora...")

Si el soporte de compilación es la razón principal detrás de la aparición de ngModule, definitivamente no debería reemplazar el alcance basado en componentes existentes para directivas y canalizaciones.
Por otro lado, basándose en la configuración de la ruta y las dependencias, el compilador angular teóricamente podría dividir el código de la aplicación en las unidades de compilación (módulos) apropiadas.

Personalmente, siento que este cambio está trayendo un mínimo de repetitivo sin mucha ventaja.

Podría argumentar que en lugar de usar módulos podríamos haber usado componentes como unidades de la aplicación. Esto es probablemente lo que la gente estaba haciendo antes del rc-5 de todos modos.

Si los módulos son necesarios para fines internos de este marco (como la carga diferida y cosas relacionadas), entonces deben ocultarse al desarrollador de alguna manera para que no contaminen el código y empeoren la experiencia de codificación. Y ni siquiera estoy hablando de mantenibilidad...

La primera vez que vi angular2 pensé: 'Oye, van en la dirección correcta con esto, parece que aprendieron algo de angular 1'. Se deshizo de los módulos internos de angular 1 y en su lugar usó módulos ES, también se aceptaron otros cambios (componentes, texto mecanografiado, etc.)

Pero cuanto más espero que esto se estabilice, más me estremezco debido a los cambios importantes, la falta de documentación y los mensajes de error deficientes. Ahora viene con este NgModules y básicamente deshace al menos una gran cosa que cambia desde angular 1.

Peor aún, si tengo una aplicación que comenzó con rc-2 o 3 (que teóricamente eran casi estables), ahora tengo que trabajar mucho para crear una buena aplicación angular2 rc-5 y necesito explicar de alguna manera el cliente y otros desarrolladores esto. E incluso si lo hago, Dios sabe qué cambiarás a continuación y mi trabajo podría haber sido en vano.

Sé que angular 2 ha sido una etapa temprana desde hace un tiempo, pero somos RC-5, las personas tienen proyectos bastante sólidos que usan Angular 2 por ahora y todavía están haciendo cambios no solo rompiendo desde el punto de vista de la API sino rompiendo como una forma de pensar en Angular.

No es bueno ngFor y algunas importaciones cambian o que la inyección de componentes cambia dinámicamente 3 veces en 5 versiones, pero puedo aceptarlo y comprenderlo. Traer cambios que rompen no solo las aplicaciones sino también la forma en que los desarrolladores piensan en este marco tan tarde en el ciclo de desarrollo que lamentablemente no puedo aceptar.

De todos modos, como puedes ver, mucha gente está de acuerdo con lo que tengo que decir y algunos están aún más enojados. Tienes un marco enorme en el que la gente confía (porque Google en su mayoría) pero no puedes apostarlo todo o podrías tener una sorpresa ya que todos tienen opciones (y cuando se habla de JS, hay MUCHAS).

Si el nuevo Módulo tuviera una plantilla, podría ser el Componente. Piénsalo.

El siguiente paso sería mover todas las variables y funciones de Componentes a la clase Módulo. Seriamente. Luego teníamos una enorme biblioteca central de _todas las acciones posibles_ dentro de nuestro módulo brillante. ¡Esto sería genial! No sé por qué te detuviste en la centralización de declaraciones y dependencias. ¡Hay muchas más líneas de código estructuradas y descentralizadas allí!

¿Alguien del equipo central puede opinar sobre todo esto? Según las notas de la última reunión semanal, el equipo sigue adelante con la eliminación de las API en desuso.

@mhevery

Todo este asunto de elevación rompió mi aplicación muy sutilmente cuando actualicé hoy.

  • Tuve que cambiar el selector de un componente de clase a elemento, porque en un componente completamente no relacionado, esa clase se usa para diseñar y de repente comenzó a crear una instancia del componente.
  • Estoy bastante seguro de que #10850 solo existe, porque tenía dos componentes llamados SpectrumComponent (una página completa para navegar sin un selector y un componente "compartido" usado en múltiples componentes para visualización con selector). Es probable que el levantamiento se confunda con eso: las declaraciones directives: no.

Para mis componentes SVG, esto ahora se convierte en un problema mayor, porque no puedo usar un elemento personalizado allí. Todavía no sé cómo abarcarlos para asegurarme de que sus selectores de clase no activen una creación de instancias de componentes en ningún otro lugar (!) de la aplicación.

Parece estar de moda en estos días ignorar el significado de "Beta" y "Release Candidate" (ASP.NET Core es otro ejemplo de alto perfil) en proyectos grandes. Pero enfrentarse a cambios de última hora que tienen el potencial de romper silenciosamente una aplicación literalmente en cualquier lugar es más frustrante de lo que debería ser. Realmente espero que las promesas que vienen con esos cambios den sus frutos pronto.

ngModules tiene sentido. Eliminar la capacidad de declarar/proporcionar a nivel de componente no lo hace.

Pequeño ejemplo

Tengo una aplicación que contiene varios cuadros de diálogo diferentes (algunos simples, llamémoslos simple-1 y simple-2, y uno complejo que contiene otros componentes, llamémoslo complejo 3).

Por el momento tengo una estructura de carpetas simple (obviamente la aplicación se queda fuera de esto)

- dialogs
   - simple-1 (containing single component and template for simple-1 dialog)
   - simple-2 (containing single component and template for simple-2 dialog)
   - complex-3 (contains the main complex-3 component plus a number of other internal components)
      - internal-component-1
      - internal-component-2
      - internal-service-3

Para mí, este es un conjunto de funciones perfecto para incluir en un módulo de funciones aislado. entonces agrego

   dialogs.module.ts
   - simple-1
   - simple-2
   - complex-3
      - internal-component-1
      - internal-component-2
      - internal-service-3

Y agrego Simple1Component, Simple2Component y Complex3Component como declaraciones a DialogsModule. Perfecto, funciona bien y tiene mucho sentido.

Pero...

¿Qué pasa con todos esos componentes internos en el complejo-3? ahora tengo dos opciones

  • Agregue todos los componentes y servicios complejos externos a DialogsModule. Esta es una mala decisión porque rompe la encapsulación del complejo-3 porque ahora todo en el módulo de diálogos sabe sobre sus componentes internos (componente-interno-1, componente-interno-2, servicio-interno-3)
  • Haga que complex-3 sea un módulo por derecho propio. Esto soluciona el problema del alcance (y creo que puedo exportar módulos de otro módulo para que el cliente solo necesite importar el módulo contenedor), pero ahora me deja con una combinación de componentes y módulos para grupos similares (diálogos).

Ninguno de estos tiene realmente sentido y, a medida que la aplicación escala, el conflicto entre los dos solo aumentará.

La única solución sensata/obvia/mantenible para mí sería usar el módulo para exportar los componentes de nivel superior (simple-1, simple-2, complejo-3) pero dejar que el complejo-3 _component_ defina sus propios componentes internos.

/ cc: @robwormald

He estado pensando en lo que @kylecordes dijo anteriormente sobre el uso del sistema de módulos Typescript existente para definir colecciones de código de grano de Courser, en lugar de agregar la nueva cosa ngModules. Me gustaría enviar un ejemplo para su consideración, que usa módulos Typescript para definir ngModules de manera 1 a 1. Los comentarios y pensamientos son bienvenidos.

https://github.com/jbalbes/autoNgModule

10901

Es posible que me haya perdido algo, pero la forma en que funciona la inyección de dependencia con módulos no cargados de forma diferida podría convertirse en un gran problema para "Proyectos grandes" (el mío no lo es y ya está sufriendo).

esto es interesante. ya tenemos una aplicación empresarial en Angular1. y estamos usando requirejs para definir paquetes para varios módulos (cada módulo contiene 10-20 directivas/servicios/filtros). empaquetamos estos paquetes en un solo archivo para producción (excepto las directivas principales). las directivas se cargan de forma diferida en la aplicación cuando se usan (tenemos una directiva central que carga de forma diferida las directivas requeridas).

nuestras plantillas de página de enrutamiento de aplicaciones están alojadas en la aplicación cms, y los usuarios de cms pueden arrastrar y soltar widgets de interfaz de usuario basados ​​en la directiva principal entre diferentes plantillas de página (es por eso que necesitábamos un soporte de carga diferida para directiva para reducir el tamaño del archivo de script principal en la carga del navegador como la mayor parte de nuestra aplicación se basa en widgets basados ​​en directivas)

Angular1 permite la carga diferida de directivas en un módulo al obtener una referencia para registrar proveedores.
¿Es posible este tipo de componentes de carga diferida en un módulo y compilarlos en dom en Angular2?

Estoy de acuerdo con lo que otros han sugerido de que ngModules es una solución que busca un problema. En mi opinión, el beneficio potencial de LazyLoading no justifica la desaprobación forzada de las directivas de componentes/dependencias de tuberías. Tal vez me equivoque aquí, pero siento que la mayoría de las aplicaciones realmente no verán ningún beneficio real de Lazy Loading, que para mí es el único beneficio real proporcionado por ngModules.

Tal vez ngModules esté intentando (y bueno, tal vez tenga éxito) hacer que la estructura/patrones de desarrollo sean más agradables, pero según lo poco que he visto y discutido la API hasta ahora, se está moviendo en una dirección que es más complicada de seguir y mantener.

Además, ¿realmente necesitamos otro sistema de módulos?

Nadie podría discutir que NgModule agrega un nuevo tipo de cosas con las que no teníamos que lidiar antes. Y yo, como cualquiera, aprecio mucho la simplicidad anterior a RC5, especialmente de programas muy pequeños, que se ha perdido. También extraño mucho poder decirle a la gente que Angular 1 tenía su propio sistema de módulos, pero con Angular 2 solo usamos el sistema de módulos del lenguaje subyacente. UPS.

Sin embargo, en realidad hay bastantes personas, incluidos muchos líderes técnicos y otros responsables de la toma de decisiones en grandes empresas que intentan construir cosas grandes, que están extremadamente interesadas en la carga diferida y la precompilación de plantillas... Ambos están sustancialmente habilitados por NgModule.

Aunque una cosa más. La parte que menos me gusta de los nuevos módulos de Angular es el nombre. La palabra módulo, está tan sobrecargada. Ayer hablé de esto para algunos otros desarrolladores aquí, y nos gusta la palabra "paquete", en cierto modo captura bien una idea similar y no tiene un montón de cosas en competencia con el mismo nombre, al menos no en el ecosistema JavaScript.

Problema de @kylecordes sobre el nombre https://github.com/angular/angular/issues/10087

¿La lógica presentada allí también no descalificaría el uso de la palabra 'módulo', ya que entra en conflicto con tantos conceptos, si no más?

@Barryrowe no podría haberlo dicho mejor, realmente parece que la mayoría de las aplicaciones no se beneficiarán de esto, ¿termina siendo una complejidad adicional? Espero que no.

Sin embargo, me pregunto si era realmente necesario hacer que este nuevo sistema de módulos de granularidad gruesa fuera completamente ortogonal al sistema de módulos subyacente, o si hubiera sido posible hacer que cada directorio de nivel superior y todos los módulos Es6 contenidos en él fueran implícitamente comprenden un NgModule de grano grueso. Quizás se podría agregar un mecanismo impulsado por una convención de este tipo además del mecanismo actual y, por lo tanto, eliminar el modelo estándar de NgModule para los proyectos que deseen seguir dicha convención.

Este es un punto clave. Los ESModules funcionan muy bien para estructurar una aplicación si la estructura correctamente. Por ejemplo, puede hacer que una exportación profundamente anidada esté fácilmente disponible en el nivel superior de su API simplemente volviendo a exportarla a un nivel superior. También estoy a favor de agregar más convenciones opcionales al marco en general.

La primera vez que vi angular2 pensé: 'Oye, van en la dirección correcta con esto, parece que aprendieron algo de angular 1'. Se deshizo de los módulos internos de angular 1 y en su lugar usó módulos ES, también se aceptaron otros cambios (componentes, texto mecanografiado, etc.)

Pero cuanto más espero que esto se estabilice, más me estremezco debido a los cambios importantes, la falta de documentación y los mensajes de error deficientes. Ahora viene con este NgModules y básicamente deshace al menos una gran cosa que cambia desde angular 1.

De hecho, se suponía que Angular 2 aprovecharía la rica tecnología web emergente que no estaba disponible cuando se desarrolló AngularJS. Sin embargo, aunque la justificación de muchas de las decisiones de diseño tomadas para Angular 2 ha sido "los componentes web deben ser compatibles", irónicamente, el marco se está desviando de los estándares en formas cada vez mayores. Ahora bien, hay buenas razones para desviarse del estándar, cuando los estándares son malos.

Siento que el marco no está utilizando sus herramientas principales a su máximo efecto. Por ejemplo, las declaraciones de TypeScript no son exactamente idiomáticas y están llenas de any y any[] . También ignoran las potentes características del lenguaje que mejoran la usabilidad y la capacidad de herramientas de las API. También contienen cosas abominables como export declare type Type = Function .

Curiosamente, parece que un buen número de decisiones han resultado estar relacionadas con Dart. Dart no es algo que le importe a la mayoría de los usuarios de Angular. Tiene una noción muy diferente de qué tipos son y cómo se usan en comparación con TypeScript. La interoperabilidad Dart <-> JavaScript a menudo no es un buen comienzo.

@aluanhaddad , la implementación del dardo se bifurcó en un proyecto separado recientemente, por lo que esperamos que algunas de sus inquietudes se resuelvan pronto.

Este cambio ha agregado un grado significativo de complejidad, tanto en términos de LOC general como de modelado mental de las dependencias de los componentes. Mis archivos de componentes son un poco más limpios, pero a expensas de una definición de dependencia explícita e in situ, y vienen con la adición de archivos .module de sensación redundante.

Reducir el modelo estándar suena como algo bueno, pero yo diría que puede ser exagerado. Además, parece que este esfuerzo de reducción del modelo en particular se describe mejor como un movimiento del modelo en lugar de una reducción total.

Creo que angular tiende hacia inicios rápidos más difíciles y complejos. Ya hay bastante con lo que lidiar en términos de configuración de la cadena de herramientas y la lista de archivos y cosas que deben entenderse (si uno quiere adherirse a las mejores prácticas) incluso para la aplicación más básica está creciendo.

. @jbalbes gracias, es bueno escuchar eso.

@radusuciu tiene toda la razón, esto no es una reducción en el modelo, sino una transferencia de ese modelo a otra área de la aplicación. Como ya han dicho otros, aquí no hay conflicto entre el alcance del nivel de componente y el alcance del nivel de NGModule. Lo que necesitamos es un alcance granular que nos permita elegir qué componentes, directivas, conductos y servicios deben estar disponibles para reducir las fallas de la aplicación en función de su uso y semántica específicos de la aplicación.

No me sorprende que los módulos agreguen aún más complejidad de dudoso valor real para el autor de la aplicación. No formaban parte del diseño original y parecen una adición tardía que solo se agregaron porque otras cosas chocaron contra una pared y no se pudieron hacer funcionar (carga diferida, compilación, etc.) sin que se hiciera otro cambio importante.

No creo que todas las implicaciones para el desarrollo de aplicaciones frente a "hacer que las otras funciones prometidas funcionen" fueran tan importantes en la agenda cuando se agregaron, pero a medida que más y más aplicaciones se convierten a RC5, comienzan a ser más claras.

Ni siquiera he comenzado a intentar convertir mi aplicación en módulos, probablemente morirá en RC4. Sé que muchas partes necesitarán ser reelaboradas por completo y todo lo que obtendría por todo ese esfuerzo es estar más cerca del próximo RC de cambio de última hora con paquetes de tiempo de ejecución aún más grandes porque la minificación, seguramente algo bastante básico y fundamental, está rota. . Se supone que los RC se vuelven más estables y se sienten más completos a medida que avanzan, pero esto simplemente no es así.

Gang, NgModule es una irritación como muchos han explicado elocuentemente. Pero en la práctica no es tan grande. Aquí (Oasis Digital / Angular Boot Camp) ya hemos actualizado numerosas cosas pequeñas, y algunas no tan pequeñas, a RC5, y se hizo en poco tiempo (después de mucho tiempo de estudio y comprensión).

La aplicación de todos se verá afectada de manera diferente. Además, creo que su actitud hacia la rotación y el cambio en Angular 2 posiblemente será diferente si se enfoca en entregar una aplicación en comparación con si también vende capacitación y soporte para Angular 2. Para mí, todo el trabajo para actualizar a RC5 sería ser un esfuerzo completamente muerto y desperdiciado: en realidad generaría beneficios negativos (paquetes más grandes), por lo que es difícil de justificar.

Solo pensé en dar mi opinión sobre la otra cara de un impulso de cinco días en nuestra plataforma para llegar a RC6 * (estamos en las noches, RC6 técnicamente aún no ha caído en el momento de escribir este artículo). Siento que, si bien mis comentarios originales siguen siendo válidos, hay una sensación de alivio por haber alcanzado este hito. Las mayores dificultades siguen siendo el uso de la nueva sintaxis de enrutamiento: ¡demasiadas reglas vacías path: '' ! (Estoy divagando) pero eso es algo que probablemente abstraigamos.

Para NgModules en los nightlies, debo decir que los mensajes de error están mejorando, lo que hace que todo el proceso sea un poco más fácil de trabajar. Los componentes y las directivas generalmente se llaman cuando no están configurados correctamente con suficiente información para que no esté caminando por un árbol de dependencia de NgModule masivo para encontrar el problema. El problema principal que enfrentamos ahora es que solo falta funcionalidad en las páginas sin mensajes de error obvios. Esto suele deberse a que un componente no se declaró o no se importó/exportó correctamente. Es un poco complicado, pero con la educación es bastante fácil de manejar. La prueba es ahora nuestro próximo empujón, está completamente muerto en el agua. Pero al igual que el empuje de la funcionalidad, llegaremos al final.

Respiramos hondo, hicimos otra cosa durante unos días y luego lo destrozamos. ¡Nos aferramos fuerte para el próximo viaje, sea lo que sea! Buena suerte a todos los que se ven afectados por esto de una manera pequeña o grande. Hubiera sido bueno tener algún tipo de diálogo del equipo de Angular sobre este tema. El problema más difícil al que nos enfrentamos fue la falta de comunicación. Todavía no sabemos qué hay en las cartas para NgModules. Las notas de la reunión de la semana pasada no ofrecieron información. ¡A ver qué pasa esta semana!

@SaltyDH Creo que este es un comentario valioso.
Creo que las quejas sobre la comunicación no son realmente apropiadas.

La gente de implementación construye la nueva versión y la gente de documentos actualiza los documentos.
Los documentos suelen estar un poco atrasados ​​por razones obvias, porque solo pueden documentarse después de que ya se haya codificado. Escribir documentos también es un trabajo duro y lento.

Si cambias al próximo lanzamiento el día en que se lanzó o incluso usas nightlies, es un poco injusto quejarse de que aún no se comunicó todo.
El equipo de Angular tampoco puede saber de antemano qué podría causar dificultades al usuario en todos los casos.

Siempre hay miembros del equipo de Angular brindando soporte en Gitter y problemas.
También debe tener en cuenta que la carga de comunicación es bastante asimétrica, con unos pocos miembros del equipo de Angular frente a miles de desarrolladores.

Estoy completamente de acuerdo en que esto es más fácil en la compilación maestra (casi RC6) con el último año o más de obsolescencias finalmente desapareciendo.

@kylecordes , ¿de qué manera es más fácil trabajar con el maestro?

El documento de diseño para NgModules (anteriormente conocido como AppModules cuando se escribió el documento de diseño) se publicó hace más de un mes antes de que se lanzara RC5, y estaba algo preparado para que llegara.
Además, dado que NgModule era un concepto más nuevo, era difícil tomarlo por completo y migrar su aplicación mediana a grande.
En cambio, lo que hice fue comprender completamente los matices de NgModules y cómo pensar en NgModules para diseñar una aplicación Angular 2. Luego creó una aplicación de autoaprendizaje con la aplicación de NgModules.
El segundo paso es: pensar en cómo la aplicación actual se puede dividir en módulos y luego migrarlos de arriba hacia abajo. creando un Módulo a la vez comenzando con AppModule. Esto realmente ayudó y la aplicación final parece más organizada.
image

Y sí, Gitter fue realmente útil al brindar ayuda en NgModule incluso antes de que se lanzara RC5. Después de RC5, tenemos documentos y blogs disponibles para que aprendamos mucho mejor.

@zoechi Sin descarrilar demasiado esta discusión, siento que debo aclarar mis comentarios. No me refería a la documentación en absoluto, la mayoría de mis conocimientos provienen de la revisión de compromisos y problemas aquí en GitHub, estoy de acuerdo con eso. Mis frustraciones provienen de la falta de representación aquí en este número, tenemos 61 comentarios y contando. Un simple, "Somos conscientes de las preocupaciones de todos aquí en este tema, realmente creemos que este es el mejor enfoque para Angular 2 y reconocemos las dificultades que causará, pero es mejor para el futuro del producto". Gitter es excelente, pero los mensajes individuales a menudo se pierden en un mar de personas que intentan comprender diferentes aspectos de Angular 2. Me acerqué a través de este medio, pero debido a las diferencias de zona horaria u otras prioridades, no pude obtener los comentarios autorizados. podría utilizar para tomar una decisión informada. Lo que ayudó fue este podcast de Aventuras en angular https://devchat.tv/adv-in-angular/106-aia-angular2-rc5-and-beyond. Esto me dio la confianza para seguir adelante con las actualizaciones de NgModule.

Todo lo mejor.

Gracias a todos por los comentarios, disculpas por haber tardado tanto en recibir una respuesta; estuvimos muy ocupados durante la última semana (migrando las aplicaciones internas de Google a NgModules, por lo que también sentimos el dolor de la refactorización)

Déjame ver si puedo aclarar algunas de las preguntas y conceptos erróneos aquí.

Lo primero que debe comprender sobre @NgModule() (y @Component y cualquier otro decorador de Angukar) es que son puramente una construcción de tiempo de compilación: existen para permitir que el compilador angular descubra un gráfico de dependencia en una aplicación.

Una versión (simplificada) de lo que hacen nuestros decoradores:

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

No cambian ni modifican el comportamiento de la clase decorada de ninguna manera, simplemente adjuntan algunos metadatos. Angular usa esos metadatos para construir su aplicación y compilar plantillas.

En el modo JiT, esto sucede "Justo a tiempo": entre la llamada a bootstrapModule y la representación de su primer componente, el compilador de Angular recupera los metadatos adjuntos a las clases mediante la API Reflect:

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

Sin embargo, en el modo AoT, esto funciona un poco diferente: en el momento de la compilación, de manera estática (es decir, sin ejecutar el código) extraemos los mismos metadatos del código fuente buscando decoradores.

Esto funciona bien cuando está arrancando un solo componente, pero hemos escuchado muchos comentarios de desarrolladores que están haciendo cosas más complejas: arrancando múltiples componentes raíz o arrancando diferentes componentes según el estado de autenticación, etc.

Entonces, si bien los decoradores de @Component nos dieron la capacidad de analizar estáticamente un Componente, no teníamos la capacidad de analizar estáticamente de manera confiable una _Aplicación_

Cosas que caen bajo el paraguas de una "aplicación"

  • PLATAFORMA_DIRECTIVAS/TUBERIAS/PROVEEDORES
  • cosas que agregaste previamente a bootstrap()
  • configuración de nivel de compilador
  • múltiples componentes raíz
  • uso del lado del servidor.

NgModules introduce la idea de un conjunto de características analizables estáticamente. Lo que es interesante es que en el modo de compilación AoT, analizamos su módulo raíz y _generamos_ una ModuleFactory para cada módulo en la aplicación; esta es la versión precompilada de un módulo, que contiene _solo_ las fábricas a las que hace referencia estáticamente en las plantillas y las que marcar como "entryComponents"

Debido a que ya extrajimos la información necesaria para la compilación antes de tiempo, en realidad podemos sacudir a los decoradores (ngc se encargará de esto automáticamente para el final), y en lugar de agrupar su aplicación comenzando en su módulo raíz, comience en su Module_Factory_ raíz generado, que solo contiene el código que realmente se usa en su aplicación, por lo que no paga una penalización por la modularidad, y las herramientas como rollup y webpack2 pueden funcionar _más_ eficientemente

más a seguir en la próxima respuesta ...

@robwormald No puedo poner en un emoji la cantidad de agradecimiento por este tipo de información de fondo.

¡Gracias!

Otro problema con el que nos encontramos que NgModules resuelve:

Considere un caso en el que desee crear un DialogService o similar.

Históricamente, harías algo como:

@Injectable()
export class MyDialogService {
  //inject the dynamic compiler 
  constructor(private componentResolver:ComponentResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //compile the component into a factory, async
    return this.componentResolver.resolveComponent(component)
      .then(componentFactory => {
         //dynamically insert the compiled componentFactory into the view:
        return target.createComponent(componentFactory);
      })
  }
}

... que usarías como

myDialogService.showDialog(MyRandomDialogComponent).then(...)

Cosas a notar aquí -

  • la compilación de componentes en modo JiT _debe_ ser asíncrona, debido a templateUrls y styleUrls externos
  • un viewContainer acepta una _componentFactory_, por lo que ahora su código tiene un problema: tiene que reescribir el código para cambiar de modo (entre JiT y AoT), _o_ siempre debe asumir que la API de inserción del componente es asíncrona. Esto podría estar bien en el caso de un cuadro de diálogo, pero si está construyendo interfaces de usuario complejas dinámicamente (piense en un tablero o una vista de cuadrícula o lo que sea), incurre en una gran cantidad de programación de Promesa innecesaria.
  • Los servicios/componentes de terceros o compartidos (como SharedDialogService) tienen el mismo problema y tienen que aceptar _ya sea_ Componentes o ComponentFactories

Este problema surge para _cualquier_ aplicación que esté realizando una inserción dinámica de componentes (que no significa necesariamente una carga diferida): diálogos, enrutadores, etc., todos esperan interactuar con ComponentTypes (las clases) en lugar de selectores (foo-bar).

Entonces, cuando agrega un Componente a su matriz de componentes de entrada en un decorador NgModule:

@NgModule({
  declarations: [ MyRandomDialogComponent ],
  entryComponents: [ MyRandomDialogComponent ]  
})
export class MyApp {}

Lo que esto le dice al compilador es "gréname un mapeo entre MyRandomDialogComponent y su MyRandomDialogComponentNgFactory compilado", y _guárdalo en NgModuleFactory en el que está declarado_

Por lo tanto, una versión impulsada por NgModule del servicio de diálogo anterior se ve así:

@Injectable()
export class MyDialogService {
  //inject the component factory resolver 
  constructor(private componentFactoryResolver:ComponentFactoryResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //*retrieve* the componentFactory by component, sync
   let componentFactory = this.componentFactoryResolver.resolveComponentFactory(component)
   //add the componentFactory to the view, sync
   return target.createComponent(componentFactory);
  }
}

Ahora, cualquier componente que haya agregado a entryModules se puede recuperar sincrónicamente e insertar dinámicamente en la vista, y su código _no_ tiene que cambiar según el modo en el que se encuentre, ni las bibliotecas compartidas/de terceros tienen que preocuparse por la compilación lógica.

Gracias por la explicación @robwormald

Una pregunta es: ¿eso requiere la eliminación de las declaraciones de directivas/tuberías? ¿Hay alguna razón por la que no puedan coexistir con NgModule?

Siento que la gente, incluyéndome a mí, está frustrada no por el NgModule "chico nuevo en el bloque" o cualquier malentendido, sino porque la "vieja forma" de hacer las cosas, que parece estar _funcionando_ bien_ con muchas personas, está siendo eliminado a la fuerza, especialmente en esta etapa tardía de RC. Creo que esta es una distinción importante de cualquier resistencia a NgModule en sí, que no he visto mucho, que aún no se ha abordado directamente.

También veo que la solicitud de extracción para eliminar las declaraciones de directivas/tuberías está activa (https://github.com/angular/angular/pull/10912). Espero que podamos obtener una respuesta sobre este punto antes de que se establezca algo. Roca.

Gracias por adelantado. Sin duda, ha sido un placer trabajar con Angular y aprecio mucho el arduo trabajo del equipo durante el año pasado+

Aquí hay algunos comentarios con respecto al "alcance global": esto no comprende la mecánica del compilador y los módulos (lo cual es completamente comprensible, esto es algo complejo).

Volcar toda su aplicación en un solo NgModule está "bien" en la forma en que volcar todo el estado de su aplicación en $ rootScope estaba "bien" en Angular1 (léase: funciona, pero su diseño de aplicación es deficiente)

En Angular 1, llevar un módulo a una aplicación más o menos "contaminaba" toda su aplicación, ya que todo se vertía en una sola bolsa de inyector.

En Angular2, NgModues tiene algunos mecanismos de alcance muy poderosos que permiten la composición sin contaminación. De nuevo, vuelve al compilador.

Cuando Angular atraviesa y compila su aplicación, cada componente que encuentra se _compila en el contexto en el que se declaró_

Por ejemplo, imagine que tiene un SharedModule con alguna funcionalidad que desea compartir en una aplicación

@Component({
  selector: 'shared-component-one',
  template: `
    <div>Shared Component One</div>
    <shared-component-two>
  `
})
export class SharedComponentOne {}

@Component({
  selector: 'shared-component-two',
  template: `
    <div>Shared Component Two</div>
  `
})
export class SharedComponentTwo {}

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

Tanto SharedComponentOne como SharedComponentTwo están _declarados_ en SharedModule; las declaraciones implican _propiedad_, por lo que ambos componentes son propiedad de SharedModule. Sin embargo, _solo_ SharedComponentOne se _exporta_ del módulo; SharedComponentTwo permanece _privado_ para SharedModule.

Si tuviera que traer SharedModule y usarlo en otro módulo, así:

@Component({
  selector: 'some-component',
  template: `
    <div>hello from some component</div>
    <shared-component-one></shared-component-one>
  `
})
export class SomeComponent {}

@NgModule({
  imports: [ SharedModule ],
  declarations: [ SomeComponent ]
})
export class SomeModule {}

...cuando el compilador comienza a compilar SomeComponent , descubre el selector shared-component-one , y porque SharedModule (que exporta SharedComponentOne ) se importa a SomeModule , sabe que shared-component-one === SharedComponentOne.

Curiosamente, cuando el compilador realmente compila SharedComponentOne, lo hace "dentro" de SharedModule, lo que le permite usar cosas dentro de SharedModule que no están expuestas al mundo exterior.

Esto es muy similar a cómo solía funcionar con Component.directives, y en este caso son iguales.

Considere, sin embargo, si tuviera algo como una función de pestañas:

@Component({
  selector: 'my-tabs',
  template: '...'
})
export class TabsComponent {}

@Component({
  selector: 'my-tab',
  template: '...'
})
export class TabComponent {}

Ambos componentes son de nivel superior, no hay una relación jerárquica en la que confiar. Esto condujo a la explosión de una especie de convención de personas que hacían

export const TAB_DIRECTIVES = [ TabsComponent, TabComponent ]

Una función de pestañas más complicada podría tener un servicio que administre varias instancias de pestañas, por lo que también debe manejar ese caso...

export const TAB_PROVIDERS = [ ... ]

y usarlo se convierte en un ejercicio para recordar todas las cosas que tienes que exportar e importar...

import {TAB_DIRECTIVES, TAB_PROVIDERS}

y luego proporcionar todas esas cosas en la ubicación correcta, en todas partes, donde desee usarlo. También es muy fácil en este punto olvidarse de importar TODAS las cosas que necesita para una función y terminar con extrañas fallas silenciosas, o componentes compilados sin todo el contexto requerido.

Con un NgModule, simplemente puede empaquetarlos en una sola unidad, pasar eso a su aplicación e importarlo donde sea relevante.

Para bibliotecas como Material Design, que puede tener una serie de funciones distribuidas en varios módulos, puede aprovechar la misma semántica de importación/exportación para que sea aún más portátil:

@NgModule({
  exports: [ TabsModule, NavbarModule ]
})
export class MaterialSharedModule {}

extraer ese único módulo permite que toda su aplicación use componentes y, nuevamente, en el momento de AoT, solo los que use se importarán al código generado.

En cuanto a por qué eliminamos Component.directives / pipes, hemos escuchado muchos comentarios en ambas direcciones. Sentimos que tener dos formas de lograr lo mismo es generalmente un mal patrón, por lo que tomamos la decisión de permitir que las personas escriban menos código en general, y aquellos que desean el alcance explícito ofrecido anteriormente por Component.directives pueden lograr la _misma_ funcionalidad al alcance a nivel de módulo.

En RC5, hicimos una especie de elevación automática de Component.directives al ámbito "global". Este fue un intento de suavizar la transición y, aunque funcionó para la mayoría de las personas, el comportamiento mixto antiguo y nuevo provocó algunos errores y comportamientos extraños que, aunque frustrantes, son temporales. Esto desaparece en RC6 (y se han mejorado los mensajes de error)

En cuanto a por qué esto cambió tan tarde en el juego, solo podemos disculparnos. No nos gusta hacer cambios de última hora más que a ninguno de vosotros. Al final del día, literalmente estamos construyendo un marco de una manera que nunca antes se ha hecho en el front-end y, por lo tanto, nos encontraremos con problemas imprevistos y problemas de diseño. Este fue uno de esos casos, y fue fuertemente debatido e investigado entre el equipo central antes de que tomáramos la decisión. Una vez más, lamentamos las molestias, pero estamos seguros de que el resultado neto es una forma mucho mejor de crear _aplicaciones_, razón por la cual estamos todos aquí.

Gracias por la paciencia de todos. Dejaré esto abierto si hay otras preguntas que no he cubierto aquí.

Robar

Buen trabajo, @robwormald

Me gustaría añadir algunas observaciones más:

proveedores

Rob se centró en _declaraciones_, _importaciones_ y _exportaciones_. Los _Proveedores_ del módulo son diferentes.

@Component.providers vidas! Solo @Component.directives y @Component.pipes desaparecerán.

Puede usar tanto @NgModules.providers como @Component.providers . Tienen diferentes propósitos:

a) @NgModules.providers _extiende_ la aplicación agregando proveedores al inyector "principal" (el inyector raíz de la aplicación para módulos cargados con entusiasmo). Así es como RouterModule agrega un servicio de enrutamiento a su aplicación sin que tenga que proporcionarlo.

b) @Component.providers _encapsula_ la prestación del servicio dentro del alcance de la instancia del componente (y su subárbol de componentes).

Ambos enfoques satisfacen diferentes necesidades.

Mi consejo general: _si tienes un proveedor en @Component hoy, déjalo ahí_

Módulos de características

Son una forma poderosa de organizar su aplicación. El capítulo Módulo Angular tiene una breve sección sobre la refactorización de un Módulo Angular monolítico a un módulo de características . Es bastante fácil (al menos lo ha sido para mí las varias veces que lo he hecho).

Busco costuras naturales en mi aplicación. No me vuelvo loco. No modularizo cada componente.

La razón por la que Material Design parece hacerlo es porque están tratando de facilitarnos el uso de lo que queremos de una manera detallada.

Tendrán un módulo de fregadero de cocina que simplemente reexporta todo. Podrías importar eso y listo. Pero si estoy ajustando mi propia aplicación, creo un _módulo de reexportación_ similar que exporta solo las partes de MD que quiero.

Este es un patrón que cualquier proveedor de bibliotecas podría seguir y podría tener sentido en la empresa donde armamos nuestros propios "kits" de dispositivos aprobados por la empresa.

Descubriendo dependencias de declaración

El compilador hace un trabajo mucho mejor ahora al decirle cuando falta algo. Si sigue la práctica recomendada y _siempre, siempre, siempre separa con guiones_ los nombres de los selectores de componentes, el compilador le informará cuando tenga un componente no declarado. También recoge enlaces y directivas de datos no declarados/no reconocidos.

Migrar de una versión anterior a RC5 promueve una sensación de pérdida. Tenemos que hacer el tedioso trabajo de descubrir dependencias en nuestras listas anteriores directives y pipes . Y tenemos que desengañar. Este es el desagrado esencial de vivir al límite.

Un RC no debería cambiar tanto

Sip. No obtendrás una discusión del equipo sobre eso. No fue intencional. Si hubiéramos sabido que necesitábamos NgModule , lo hubiéramos tenido en versión beta.

Pero, en mi opinión, es mejor enviar el producto correcto que seguir servilmente alguna noción de lo que debería ser un RC y entregar el producto incorrecto. Además... y no es mucho consuelo decirlo... pero si ha estado observando algunas otras compañías de software importantes recientemente, es posible que haya notado una noción equivalentemente flexible de "candidato de lanzamiento". Es la forma en que nuestra industria va por alguna razón.

Ahora he convertido varias aplicaciones y he ayudado a otros a hacerlo. Una vez pasada la fase "_movieron mi queso (otra vez)_", es una migración bastante mecánica y todos parecen pensar que están en un lugar mejor. Tal vez solo están siendo amables conmigo. OTOH, no salgo con personas que son tan agradables ;-)

(también, re: el nombre)
Nos deshicimos de nombres hasta la muerte. Inicialmente se llamaban AppModules (ya que describen algo de un nivel más alto que un componente, una "Aplicación") pero no era un término lo suficientemente amplio. Paquetes, bultos, barriles, globos, etc.

Tenga en cuenta que no es un reemplazo para los módulos ES: es un aumento que permitirá que los módulos ES y el movimiento del árbol funcionen mejor para todos los desarrolladores angulares, y semánticamente, son similares a cómo funcionan los módulos ES (importaciones, exportaciones, declaraciones)

Entonces, nombrar es difícil. NgModule es.

Tenemos la API completa para 2.0.0, por lo que observaremos los próximos meses después del lanzamiento para ver qué patrones se desarrollan y dónde podemos mejorar y hacer mejores inferencias para 2.1.

Gracias sinceramente @robwormald @wardbell por los comentarios tan perspicaces. Creo que para mí el mayor alivio es

"Tenemos la API completa para 2.0.0, por lo que observaremos los próximos meses después del lanzamiento para ver qué patrones se desarrollan y dónde podemos mejorar y hacer mejores inferencias para 2.1".

Es algo que ya escuchamos hace unas semanas, pero ahora es específicamente en el contexto de NgModules junto con todos estos comentarios. Es la confianza que necesitaba para ir a una Junta y decir. Hemos terminado aquí, es hora de terminar de construir nuestra aplicación. ¡También quiero extender mis felicitaciones a todo el equipo y la comunidad de ng2 por alcanzar este hito! Tiempos emocionantes por delante.

Sinceramente, creo que puedes decir que @SaltyDH. La rotación de Angular 2 ha terminado.

Eso no significa que Angular 2 haya terminado de evolucionar. Habrá lanzamientos futuros. ¡Pero la rotación que conduce a 2.0... ha... terminado!

Muchas gracias por la honestidad y los casos de uso explícitos, muchachos. Realmente ayuda

Solo un pensamiento rápido sobre la denominación y la duplicación en la API para NgModule, que creo que es un poco engorroso.

OMI esto:

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

... podría ser más claro y más conciso como:

@NgModule({
  private: [ SharedComponentTwo ],
  public: [ SharedComponentOne ]
})
export class SharedModule {}

1) WRT para nombrar (público y privado frente a declaraciones y exportaciones), es esencialmente cómo @robwormald arriba y estoy seguro de que muchos otros lo están explicando

2) (Ignorando el nombre) ¿por qué debería repetirse SharedComponentOne ? Seguramente podría decir que si se trata de una "exportación", debe ser una "declaración", ¿entonces podría ser desazucarado de esa manera?

Solo mis dos centavos en algo altamente subjetivo 😄 - ¡gracias nuevamente por las explicaciones detalladas!

@robwormald @wardbell Gracias por las explicaciones detalladas.

Y como dije anteriormente en este hilo NgModules nos ayudan a organizarnos mejor. Un ejemplo reciente es la creación de directivas de validación para formularios controlados por plantillas. Pre RC5 teníamos que importar cada directiva en el componente donde estamos creando un formulario. Ahora simplemente lo empaquetamos en VaildatorModule e importamos el módulo donde sea necesario. Cualquier Validador que añadamos más adelante, estará automáticamente disponible para los módulos donde haya importado ValidatorModule . Solo necesito actualizar la plantilla sin preocuparme por las dependencias.

@JamesHenry declarations , imports y exports se usan para mantener NgModules en línea con los módulos ES6 como nosotros import , export y declare cosas en módulos ES6.
Estoy de acuerdo con el azucarado, las cosas que se exportan se pueden desazucarar en declaraciones automáticas mágicamente.

@JamesHenry

1), nos quedamos con las importaciones/exportaciones porque el modelo mental está más cerca de cómo funcionan los módulos es (al menos en términos de alcance): declara cosas en un módulo, importa cosas de otros módulos y exporta cosas para que estén disponibles para otros.

2) if it is an "export" it must be a declaration, so it could just be desugared that way? -> esto funciona hasta que use un ngModule para volver a exportar, como en el ejemplo de MaterialModule anterior: hay muchos casos en los que puede usar un ngModule para volver a exportar algo declarado en otro módulo, y entonces las inferencias se desmoronan.

@robwormald ¡Excelentes comentarios! Definitivamente merece una publicación en el blog.

Tengo una biblioteca de diálogo que usa @NgModule ahora y puedo decir que veo a los usuarios luchando mientras intentan agregar componentes personalizados, ya que se olvidan de registrarlos en entryComponents , aparentemente esto no es lo suficientemente claro, pero comprensible ya que es una función avanzada...

Estoy seguro de que se hundirá con el tiempo.

@shlomiassaf gracias!

Debería mencionar también, para casos como el suyo:

Tenga en cuenta que cuando usa el enrutador de angular, agrega componentes a las declaraciones y la configuración de la ruta, pero _no_ a los componentes de entrada, a pesar de que el enrutador es la definición misma de los componentes de entrada. (recuerde: componente de entrada === cosa a la que desea referirse por Clase, en lugar de selector)

Hay un truco genial que cualquier biblioteca puede aprovechar: hay un token mágico llamado ANALYZE_FOR_ENTRY_COMPONENTS ; consulte https://github.com/angular/angular/blob/master/modules/%40angular/router/src/ router_module.ts#L117 para saber cómo lo usa el enrutador.

Entonces, para las bibliotecas que se ocupan de los componentes insertados dinámicamente, podría hacer algo como:

@NgModule({
  providers: [ DialogService ]
})
export class DialogModule {
  static withComponents(componentList): NgModuleWithProviders {
    return {
      ngModule: DialogModule,
      providers : [
         { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: componentList, multi: true }
      ]
     }
  }
}

usado como

@NgModule({
  declarations: [ MyConfirmDialog, MyQuestionDialog ],
  imports: [
    DialogModule.withComponents([ MyConfirmDialog, MyQuestionDialog ])
  ]
})
export class MyAppModule {}

Puede funcionar para su caso de uso, puede que no.

@JamesHenry Es muy importante que declarations no se confunda con private . Estás diciendo _Este módulo declara este componente_. No estás haciendo ninguna declaración sobre lo público o lo privado. Estás haciendo un reclamo de propiedad.

Realmente es como lo que sucede en los módulos ES6. Cualquier cosa que defina dentro del archivo "pertenece" al módulo definido por ese archivo. Si es público o no, depende del uso que haga de la palabra clave export .

Y al igual que con los módulos ES6, puede volver a exportar cosas que importó.

Me gusta pensar en declarations como el "truco" que evita que tenga que colocar físicamente todos mis componentes, directivas y canalizaciones en el mismo archivo físico (como tendría que hacer con los módulos ES6 si tuviera la intención todas esas clases pertenecen al mismo módulo ES6).

Entonces, para mí, declarations es un sustituto de pegar esos archivos en un archivo terriblemente grande. Ese es _mi_ modelo mental de todos modos.

Una cosa a tener en cuenta es la diferencia lógica entre proveedores y componentes en el contexto de un módulo.

Los proveedores y los componentes se declaran en el mismo lugar ( NgModuleMetadataType ), por lo que un desarrollador puede sentir intuitivamente que los proveedores se comportan como componentes... lo que significa pensar que un proveedor en un módulo resultará en una instancia para ese módulo... .

Dado que los proveedores son administrados por el DI, por supuesto, esto no es cierto, en realidad están a nivel de aplicación.
Los componentes de un módulo son privados si no se exportan, lo que podría generar confusión.

Me encanta el concepto de módulos, en mi opinión, el único problema en la API es tener proveedores y componentes declarados en el mismo lugar dentro de un módulo... para los recién llegados es algo difícil de entender.

@wardbell ¡ Gracias Ward, eso es realmente genial! Solo para aclarar, ya que esto acaba de surgir en las discusiones, cuando decimos que Angular 2 tiene API completa, ¿de qué espacios de nombres estamos hablando aquí? @angular/???

@robwormald ¡Gracias! ¡¡¡Un gran consejo!!!
¡Uno con sabor a azúcar! implementará.

No soy un empleado de Google y tal vez un empleado de Google no podría decirlo. Solo puedo informar lo que estoy viendo con mis propios ojos: un congelamiento de API muy grave en el conjunto de bibliotecas @angular/ .

Hay buenas ideas que están en el estante porque no eran lo suficientemente buenas o profundas como para justificar la suspensión del lanzamiento. Así es como debería ser. Las buenas ideas nunca cesan. Pero ha llegado el momento de decir _Este es tu Angular 2.0_.

Tenemos la eliminación prometida de la API en desuso entre ahora y "final". Eso tiene ajustes... como cualquiera puede ver mirando al maestro. Siento que hemos terminado.

@wardbell Me hago eco de lo que dices sobre las exportaciones.
El index.ts se llenó una vez con

export * from 'a.component'
export * from 'b.component'
export * from 'c.component'
export * from 'p.directive'
export * from 'x.service'
export * from 'z.pipe'

ahora se reduce a solo export * from my.module
el resto de las cosas limpias se encuentra en las exportaciones de NgModule como
exports: [ AComponent, BComponent, CComponent, PDirective ] y así sucesivamente

@wardbell Creo que @NgModules.providers debería haber sido @NgModules.rootProviders o @NgModules.appProviders .

Siento que describe claramente el contexto de los proveedores.

@shlomiassaf Eso sería engañoso. El efecto de @NgModules.providers es diferente para módulos ansiosos y perezosos. Los módulos con carga diferida obtienen su propio inyector secundario, lo que significa que _sus proveedores_ se agregan al inyector _secundario_, no al inyector _raíz_. Y así sucede si un perezoso cargó un perezoso cargó un perezoso.

Tal vez podría haber sido un nombre diferente. Tu sabes como es eso. Pero rootProviders no habría sido una mejora por las razones que acabo de dar.

@wardbell estuvo de acuerdo, no pensó en ese escenario.

Solo quería agregar al sentimiento que las respuestas exhaustivas y la comunicación son muy apreciadas. Si este es de hecho el último de los dolores de crecimiento de rc-a-final, entonces nos vamos a las carreras. ¡Gracias!

Como han comentado otros, se agradecen los comentarios del equipo. Sin embargo, este tipo de cambio durante esta fase de desarrollo sugiere errores de diseño fundamentales.
Seamos honestos con nosotros mismos, todos hemos cometido este tipo de errores, por lo que no vale la pena juzgar, pero cuando cometo un error, me siento humilde y, con suerte, me hará más prudente. No me da la impresión de que esté teniendo el mismo efecto en el equipo de Anagular.

Me gusta pensar en las declaraciones como el "truco" que evita que tenga que colocar físicamente todos mis componentes, directivas y canalizaciones en el mismo archivo físico (como tendría que hacer con los módulos ES6 si tuviera la intención de que todas esas clases pertenecen al mismo módulo ES6).

Entonces, para mí, las declaraciones son un sustituto de pegar esos archivos en un archivo terriblemente grande. Ese es mi modelo mental de todos modos.

@wardbell Tal vez me estoy perdiendo algo fundamental, pero no veo cómo usar NgModule.declarations es fundamentalmente diferente de importar todos, pero solo reexportar algunos, de sus ESModules. Irónicamente, la principal limitación de ESModules es que solo contemplan el concepto de módulos físicos, no lógicos. No veo cómo NgModule mejora eso. Es solo una sintaxis de agregación diferente, pero no eleva el nivel de abstracción a un grado significativo.

Además, NgModules falla por completo en abordar un problema importante:

Todo el patrón Function[] es opaco en todos los sentidos. Reduce la detectabilidad a cero. Uno tiene que leer la fuente para determinar qué hay en una variedad de proveedores. Lo mismo ocurre con NgModule.exports .

Pero, en mi opinión, es mejor enviar el producto correcto que seguir servilmente alguna noción de lo que debería ser un RC y entregar el producto incorrecto. Además... y no es mucho consuelo decirlo... pero si ha estado observando algunas otras compañías de software importantes recientemente, es posible que haya notado una noción equivalentemente flexible de "candidato de lanzamiento". Es la forma en que nuestra industria va por alguna razón.

@wardbell La mayor frustración sobre RC para mí es la impresión de que una Beta acaba de ser empujada a RC debido a ng-conf y google i/o. Para avanzar, la razón debe ser clara: ha sido _marketing_ y como tecnólogos debemos luchar contra la tendencia de estas nociones flexibles de madurez. Es posible que conozca a un fabricante de automóviles popular en el valle donde la discusión es sobre si ha sido correcto vender una versión beta de un producto porque puede costar una vida. No quiero exagerar, pero como tecnólogos debemos hablar si esa es la forma en que va nuestra industria porque entonces va en la dirección equivocada.

Me gusta el enfoque de ngmodule pero tengo una pregunta @robwormald :

Tengo un servicio compartido que no tiene componentes, directivas ni conductos. Solo tiene servicios ( forRoot ) y contiene todas las clases de modelo de negocio. El app.module importa ServerApiModule.forRoot() por lo que los servicios están disponibles para toda la aplicación. ¿Deberían los módulos de características, que utilizan los servicios y las clases de modelo de negocio, importar este módulo compartido? Técnicamente no es necesario (sin errores) pero desde el punto de vista semántico tendría sentido (también sin errores). ¿Qué debemos hacer con ese tipo de módulos? ¿Importarlos o no? Personalmente, me gusta la segunda posibilidad porque dice 'Oye, soy un módulo de funciones y necesito estos servicios y necesito estas clases de modelo de negocio'.

¡Gracias por una respuesta!

Entonces puedo sentir el dolor con bibliotecas/bibliotecas de aplicaciones modulares y ngModule.

Pero como se ha dicho muchas veces, no mezcle dos formas posibles. Eso es y será confuso.

Entonces, el enfoque correcto sería declarar un ngModule para cada componente.
Pero como esto hace que sea mucho más un codificador de caldera para cada componente, esa forma tampoco funciona a gran escala.

Por lo tanto, no agregue un nuevo decorador llamado ComponentModule que sea más o menos dulce para evitar declarar el componente y el módulo como material.

¿De esta manera? Si veo un componente. Sé que DEBE ser parte de un ngModule. Si tengo un caso para muchos componentes para agruparlos, PUEDO usar NgModule. Si solo quiero un componente independiente como los "componentes antiguos", uso ComponentModule y SÉ todas las dependencias y que puede ser una dependencia de Módulo para otros módulos, pero no parte de ellos.

@nathraQ si el enfoque correcto es usar NgModule para cada Componente, y es posible que así sea, entonces NgModule no debería haberse introducido y Componente debería haberse mejorado. Con respecto a la plantilla, Angular 2 es tan pesado que apenas importa en este punto.

Muchos marcos que no tienen su propio sistema de módulos han usado convenciones con mucho éxito para establecer patrones estándar para el diseño y la visibilidad de las construcciones. Un hombre sabio dijo una vez que no se pueden definir las convenciones a posteriori; que tienen que estar ahí desde el principio. Era escéptico ante esta afirmación, pero esta debacle demuestra que tenía razón.

@aluanhaddad lo siento, no estoy de acuerdo. Tenía mis casos de uso para un solo módulo en angular 1.x con administración de dependencia personalizada (como el iniciador de este hilo), pero también tenía casos de uso para módulos para agrupar un conjunto de controladores, directivas y servicios.

Ambos son útiles. Ahora tenemos que descubrir cómo integrarlo comprensible para todos.

Wow, eso fue una lectura larga :smile:

Puedo ver los pros y los contras del nuevo cambio, pero me hizo pensar en un escenario con el que tuve problemas en Angular 1.

@wardbell @robwormald -

Si uso el patrón SharedModule e importo dos bibliotecas de terceros (¿ui-bootsrap vs angular-strap, alguien?) que usan el mismo selector para un componente, digamos my-selectbox

¿Recibiré un error si trato de importarlos a ambos? ¿derecho?

Una solución que leí aquí es volver a exportar una de las bibliotecas en un módulo personalizado
Pero eso significa que debo seguir actualizando el módulo contenedor cada vez que la biblioteca se actualice, ¿no?

Además, puede suceder que tenga mi propio selector de componentes con el mismo nombre (y en proyectos grandes eso puede suceder más de una vez)

¿Hay una solución recomendada para este problema? ¿O es el "módulo contenedor"?
(Espero que no volvamos a usar un prefijo para los selectores, eso no fue divertido)

¡Gracias por adelantado!

El espacio de nombres, o prefijo como algunos lo llaman, generalmente es una buena idea, sin importar cuán grande sea su proyecto. Sí, puede ser más trivial en proyectos más pequeños, pero tan pronto como se involucren módulos de terceros, diría que es casi un requisito; como mínimo, brinda tranquilidad al saber que las colisiones no ocurrirán incluso cuando se actualicen otros módulos. , pero también los desarrolladores pueden identificar fácilmente lo que pertenece a cada módulo sin tener que seguir necesariamente el árbol de dependencias.

@nathraQ Todos estos patrones se pueden lograr con módulos ECMAScript. La introducción de NgModule no nos lleva a ninguna parte y el hecho de que las bibliotecas como AngularMaterial estén convirtiendo los componentes en NgModules solo para preservar la encapsulación proporcionada anteriormente solo prueba el punto.

@aluanhaddad NgModules está tratando de hacer algo muy diferente a los módulos ES y tampoco está reemplazando la encapsulación de componentes, es decir, tanto los módulos ES como los componentes no han cambiado sus responsabilidades principales. NgModules es el medio a través del cual describe la arquitectura en toda su aplicación, y esto ayuda a Angular a comprender mejor su intención y optimizar en consecuencia, lo que permite cosas como compilar ciertas partes de su aplicación de antemano, servir módulos resueltos dinámicamente desde un servidor, y así sucesivamente, todo de los cuales no se puede lograr con módulos ES. Por las mismas razones, un NgModule por componente no es la regla general a seguir.

Es cierto que las aplicaciones más simples pueden no beneficiarse tanto de esos beneficios, pero en esos casos NgModules debería ser menos "molesto" de todos modos.

@emilio-martinez, como escribió @aluanhaddad , ES6 y el "antiguo angular de 2 vías" nos dieron el espacio de nombres que necesitábamos.

He trabajado en proyectos muy grandes con Angular 1, con un selector llamado: mb-product-list puede colisionar muy rápidamente con otros si se trata de un proyecto grande (incluso en un equipo de más de 5 desarrolladores).

Al tratar de resolverlo con más espacios de nombres, termina con: mb-somefeature-product-list lo que hace que las plantillas se vean sucias.

Me alegró mucho ver que se resolvió en ng2 debido a los metadatos directives .
Puede npm instalar cualquier paquete que desee e importar solo lo que necesita de él por componente.

ngModules tiene sus beneficios, eso es seguro, ayuda con la carga de fragmentos asíncronos y también nos ayuda a escribir menos importaciones y mejora la productividad.

Pero usar el patrón SharedModule introduce un espacio de nombres global, muy parecido al que teníamos en ng1.

Al menos con los proveedores, tiene un espacio de nombres por el token ES6, la ubicación del archivo.

Con componentes, por culpa de los selectores, gritará que hay dos componentes con el mismo selector.

Ojalá tuviéramos alguna manera fácil de configurar un espacio de nombres especial para casos de uso de colisiones con componentes compartidos locales o de terceros.

Algo así como "anulación del selector".

Eso es lo que estaba preguntando

Gracias @robwormald por su información detallada, pero una cosa de los novatos como yo (principalmente, soy un desarrollador de back-end). Estoy aprendiendo Angular 2 y con mecanografiado. Así que el concepto del módulo ES6 es un poco borroso para mí.
Tenemos una estructura de aplicación compleja. Es una aplicación de análisis, donde mi recuento de componentes es casi 60.
Y creo que está bien estructurado bajo RC4. Aparte de Login, no usamos ningún tipo de enrutamiento, porque routern recrea todo el componente. Así que estamos planeando como una aplicación basada en pestañas. Hay dos pestañas principales (1. Análisis 2. Tablero).
La pestaña Análisis tendrá múltiples pestañas, cada una con un solo análisis debajo. El tablero también tendrá
múltiples pestañas, pero cada pestaña constará de múltiples análisis que se guardaron en
la sección de análisis. Entonces, yendo y viniendo de varias pestañas (tanto en el tablero como en el análisis)
y también cambiar entre la pestaña Tablero y la pestaña Análisis, creemos que el enrutamiento no servirá
nuestro propósito (corríjanme si estoy diciendo algo tonto).
Ahora el RC5 NgModule está rompiendo nuestra aplicación. Realmente no sabemos cómo
rediseñar nuestra aplicación. ¿Podemos realmente usar la compilación AoT en nuestra aplicación? no es
¿Todo el asunto de AoT se basa en el enrutamiento?

@shairez NgModules proporciona exactamente este tipo de espacio de nombres. Déjame tratar de aclarar esto un poco más...

La clave a tener en cuenta aquí es que un componente se compila, más o menos, "dentro" del módulo en el que se declara; consulte https://plnkr.co/edit/9w10b1Y8Bjr5DDIxOwnC?p=preview para ver un ejemplo.

Tenga en cuenta que hay dos selectores en conflicto ( my-generic-selector ): cada uno de los módulos de características importa uno de ellos, puede usarlo internamente en ese módulo, sin contaminar ningún espacio de nombres "global".

tan usado como

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one></feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two></feature-two>
</my-app>

se expande a

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one>
    <!-- the generic imported in FeatureModuleOne -->
     <my-generic-selector></my-generic-selector>
  </feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two>
    <!-- the generic imported in FeatureModuleTwo -->
    <my-generic-selector></my-generic-selector>
  </feature-two>
</my-app>

sin ningún conflicto, porque cuando el compilador compila la característica uno y la característica dos, lo hace _en el contexto del módulo al que pertenecen_, lo que evita contaminar un alcance global.

@robwormald Claro, eso es increíble y es mejor que Angular 1 en ese sentido.

El caso de uso sobre el que escribí se refería al patrón de usar un SharedModule global como se sugiere en los documentos .

Si trato de declarar tanto GenericSelectorFeatureOne como GenericSelectorFeatureTwo dentro de SharedModule , obtendré un error, ¿verdad?

O si SharedModule tiene un montón de componentes comunes útiles y quiero importarlo a cada módulo de características.

Si mi módulo de características tiene un selector en colisión, o algún tercero tiene un selector en colisión con una de las bibliotecas existentes exportadas en SharedModule , generará un error, ¿verdad?

@shairez Creo que la mayoría de las aplicaciones terminarán con una cantidad de "SharedModules", y la probabilidad de colisiones es baja: los módulos son baratos, por lo que no hay un gran costo por tener muchos.

Si tiene ideas sobre cómo mejorar los documentos, un PR será bienvenido.

Gracias, esa es la respuesta que estaba buscando, lo probaré.

Todavía no tengo mejores ideas sobre cómo resolver esto con la nueva forma de escribir módulos, por eso lo pregunté aquí, pero una vez que pruebe la solución de módulos compartidos múltiples, tendré más material para discutirlo con @ wardbell y envíe un PR.

¡Gracias por la ayuda @robwormald !

De los documentos más recientes disponibles en https://angular.io , hay _muchas_ advertencias sobre antipatrones y errores que pueden surgir fácilmente si NgModule s se componen incorrectamente. Por ejemplo

No especifique proveedores de singleton para toda la aplicación en un módulo compartido. Un módulo con carga diferida que importe ese módulo compartido hará su propia copia del servicio.

Eso es bastante preocupante. Si sigue el enfoque probado y verdadero de _primero haga que funcione, luego hágalo rápido_, es probable que deba ajustar qué módulos se cargan con entusiasmo o pereza en función de las métricas empíricas y la estructura emergente de estos módulos a medida que se expande su aplicación o biblioteca. Básicamente, ¿por qué debería importarle a un módulo si se carga con pereza o con entusiasmo?

Otro problema aparentemente más serio surge al yuxtaponer las siguientes secciones de los documentos

Supongamos que un módulo requiere un HttpBackend personalizado que agrega un encabezado especial para todas las solicitudes Http. Si otro módulo en otra parte de la aplicación también personaliza HttpBackend o simplemente importa HttpModule, podría anular el proveedor HttpBackend de este módulo y perder el encabezado especial. El servidor rechazará las solicitudes http de este módulo.
Evite este problema importando HttpModule solo en AppModule, el módulo raíz de la aplicación.

¿Puedo volver a exportar clases y módulos?
¡Absolutamente!
Los módulos son una excelente manera de agregar selectivamente clases de otros módulos y volver a exportarlos en un módulo de conveniencia consolidado.
Un módulo puede volver a exportar módulos completos, lo que efectivamente vuelve a exportar todas sus clases exportadas. El propio BrowserModule de Angular exporta un par de módulos como este:
exportaciones: [CommonModule, ApplicationModule]
Un módulo puede exportar una combinación de sus propias declaraciones, clases importadas seleccionadas y módulos importados.

Entonces, por un lado, los documentos desalientan a los usuarios a volver a exportar ciertos módulos, mientras que al mismo tiempo afirman que hacerlo brinda una gran comodidad.

La noción de reexportaciones de NgModule es análoga a la de las reexportaciones del módulo ES, excepto que usted tiene menos control. JavaScript tiene un alcance estático (sí, sé que this no lo es) y esa es una de sus mayores fortalezas, lo que permite una composición extremadamente flexible y ocultación de información. JavaScript también admite el sombreado para que siempre tenga una forma de anular un alcance.

Sin embargo, el mayor problema es que todos los ejemplos en las pautas giran en torno a cómo importar los módulos del marco @angular/*. Estos se pueden dividir naturalmente de manera que permitan prevenir conflictos de manera intuitiva. Esto se debe a que existen para proporcionar servicios de nivel de infraestructura que generalmente no se superponen. Los módulos definidos por el usuario pueden atravesar muchas capas y pueden querer mejorar o cambiar una variedad de comportamientos. Por ejemplo, un módulo de registro puede querer acceder a los servicios de enrutador y Http y, al mismo tiempo, proporcionar varios componentes para mostrar información a los usuarios administrativos y usar uno de los módulos de formularios para definirlos.

Los documentos no dicen nada sobre si las reexportaciones son transitivas... El Módulo A reexporta CommonModule. El Módulo B reexporta el Módulo A. El Módulo C importa el Módulo B. ¿Eso significa que el Módulo C ahora puede usar directivas de CommonModule?

@Martin-Wegner ¡Son transitivos como se describe aquí https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#! #q-reexportar

@aluanhaddad donde? No puedo encontrar ninguna palabra sobre reexportaciones transitivas con más de un salto...

Al leer lo que @aluanhaddad tomó de los documentos de angular, siento que tengo que reconsiderar todo lo que aprendí sobre Angular 2 y tal vez incluso si no hay un marco que maneje las dependencias de una mejor manera.

Según tengo entendido. Si tengo un módulo de aplicación que importa HttpModule y tengo un módulo de funciones con un servicio que usa el servicio Http, no debería importar HttpModule en el nivel del módulo de funciones sino en el nivel del módulo de aplicaciones. Entonces, ¿qué sucede si creo un módulo de funciones que se comparte entre muchos módulos de aplicaciones? Realmente tengo que importar HttpModule en el módulo de la aplicación. No puedo decir que mi Módulo de funciones depende del HttpModule. Eso es realmente feo y significa que la definición de NgModule carece de muchas características como, por ejemplo, PeerDependecies.
Oh chico. Se siente como si Angular 2 se estuviera rompiendo. Me temo que es hora de comenzar de nuevo, abandonar angular 2 y comenzar con angular 3.

De hecho, hay mucho sentido en lo que acabas de decir. comencé esto
viaje angular2 desde el año pasado y no he tenido ninguna razón para sentir latidos
a pesar de todos los cambios importantes que hemos visto hasta ahora (de alfa a beta,
y CR). Es comprensible en esas fases y desde que se atascó religiosamente.
a la filosofía que usó para sacarme de mi Backbonejs minimalista.
Toda la idea de este ngModules para mí ha resultado algo contraria
productivo. Y es triste ver todo el tiempo que dediqué a evangelizar a los
rica bondad de los "Componentes" minimalistas y sin hinchazón ir a
absolutamente desperdicio.
El 29 de agosto de 2016 a las 9:44 a. m., "Daniel Schuba" [email protected] escribió:

Leyendo lo que @aluanhaddad https://github.com/aluanhaddad tomó de
los documentos de angular Siento que tengo que reconsiderar todo lo que he
aprendido sobre Angular 2 y tal vez incluso si no hay un marco que
maneja las dependencias de una mejor manera.

Según tengo entendido. Si tengo un módulo de aplicación que importa HttpModule y
tengo un módulo de funciones con un servicio, que usa el servicio Http, no debería
importe HttpModule en el nivel del módulo de funciones pero en el nivel del módulo de la aplicación. Y qué
si creo un módulo de funciones que se comparte entre muchos módulos de aplicaciones? yo tengo
realmente en HttpModule siendo importado en el módulo de la aplicación. no puedo decir,
que mi módulo de funciones depende de HttpModule. Eso es realmente feo y
significa que la definición de NgModule carece de muchas características como, por ejemplo,
Dependencias de pares.
Oh chico. Se siente como si Angular 2 se estuviera rompiendo. me temo que es hora de
comience de nuevo, abandone angular 2 y comience con angular 3.


Estás recibiendo esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/angular/angular/issues/10552#issuecomment-243066961 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AF675h8_np9i5cHgL8mMOOu8vMMQmWKkks5qkpv8gaJpZM4Jee-o
.

Alguien podría corregirme si me equivoco.

Estoy pensando en organizar una aplicación de la siguiente manera.

aplicación
|--Ley/
|----Muchos Componentes.
|----LawNGModule.
|--Usuario/
|----Muchos Componentes
|----MóduloNGUsuario
|--AppNGModule
|--AlgunosComponentesPrimerNivel

Digamos que quiero trabajar con material angular. Antes odiaba un poco tener demasiada placa de caldera importando cada elemento en cada componente. Ahora lo agregaría al módulo NG. Pero como decidí usar un módulo ng por característica, tengo que hacer las importaciones para cada módulo ng que considere. No solo la raíz. ¿Está bien?

¿O tal vez este es un caso en el que crea un módulo x para volver a exportar y (Material) otro módulo, y lo importa en los módulos que necesita?

@ReneVallecillo Tienes razón. Tienes que importarlo en cada módulo de funciones. O lo agrega junto con otros módulos en un módulo compartido (ocultando la dependencia), que lo reexporta y luego usa este módulo compartido. Y si lo vuelve a exportar en otro módulo, es posible que incluso tenga importaciones duplicadas sin saberlo y verlo de inmediato.

@robwormald En respuesta a su comentario anterior :

Sin embargo, en el modo AoT, esto funciona un poco diferente: en el momento de la compilación, extraemos estáticamente (es decir, sin ejecutar su código) los mismos metadatos del código fuente al buscar decoradores.

¿Significa esto que está extrayendo módulos de forma estática del código fuente original y, como tal, no podemos crear módulos de forma dinámica?

Para facilitar la migración, estaba pensando en crear una función que creara módulos dinámicamente; algo como esto:

function createModule (entryComponent: Type, dependencies: Type[]) {
    @NgModule({
        imports: [CommonModule, FormsModule],
        declarations: [entryComponent, ...dependencies],
        exports: [entyComponent]
    })
    class FeatureComponent {}
    return FeatureComponent;
}

Entonces, si bien esto (¿probablemente?) Funcionaría con la compilación JIT, no funcionaría con AoT porque AoT analiza estáticamente el código fuente, buscando decoradores.

Esta complejidad innecesaria en una era de ES@next.... @aluanhaddad hace algunos puntos muy buenos.

Tal como están las cosas, no puedo ver a mi yo/equipo avanzando con Angular 2 si esta es la dirección prevista. Y parece que lo es, ya que esto ha sido "cerrado".

Puede que tenga que hacer como @DaSchTour e investigar otros marcos front-end. Lástima, porque hace unos meses, fue un placer trabajar con NG2 y mi elección obvia de la camada.

@iyobo aparte del dolor inicial de cambiar, la _gran_ mayoría (y hablo con _muchos_ desarrolladores) de comentarios sobre NgModules ha sido positiva.

Visto de forma aislada en una aplicación hello world, podría argumentar que es "complejo" ("innecesario" es objetivamente incorrecto, según la explicación anterior), pero realmente se destacan en una aplicación real: funciones de organización, enrutamiento perezoso y AoT se simplifica mucho con NgModules. Dada la elección hoy, todavía optaría por agregar NgModules al marco.

Estoy con @robwormald aquí, el dolor inicial de migrar de RC4/5 a NgModules fue manejable después de ver las ventajas de no tener que importar cada componente/tubería en una página recién creada.
NgModules comienza a brillar después de volverse un poco más complejo y tener muchos componentes compartidos.

Mucho más fácil simplemente importar SharedModule y terminar con él.

Hola @robwormald , la noción de que uno no está de acuerdo con la dirección actual de Ng2 no es de ninguna manera una afirmación fáctica de que solo funcionan en aplicaciones de nivel "hola mundo".

Esta "compartimentación de características" de la que hablas no es nada nuevo. Es algo que siempre se ha diseñado según las necesidades para adaptarse a cada producto/solución individual que utiliza componentes.
Dicho esto, todavía no hay mayor compartimentación que un componente que declara lo que necesita por sí mismo.

Ahora, en cuanto a la carga diferida, retroceder y mirar las cosas desde la perspectiva de un pájaro, la mayor ventaja de la carga diferida es mejorar la velocidad de carga de la aplicación. Creo que la mayoría de nosotros tenemos tuberías que hacen que esto funcione. Ingrese minificación, compresión y múltiples puntos de entrada de aplicaciones al estilo del paquete web.

Simplemente me parece que NgModules es una solución en busca de un problema, que una solución a un problema real. Pero, de nuevo, no puedo afirmar que lo sé todo...

Creo que el tiempo dirá si la introducción de NgModules fue una buena idea. Tengo la impresión de que Angular 2 actualmente solo está hecho para alcanzar ciertos objetivos de diseño. Nadie ha pensado en cosas como equipos con diferentes niveles de habilidad, código que envejece y que se transmite a través de generaciones de desarrolladores. En un mundo ideal, puede parecer una gran idea. Pero, en realidad, NgModules presenta muchas trampas y ofuscaciones que causarán muchos problemas en la fase de capacitación e introducción a un nuevo proyecto. Simplemente no es tan simple e intuitivo como lo era con la declaración a nivel de componente. Las dependencias están ocultas en los módulos y es solo cuestión de tiempo que tenga que comenzar a buscar el módulo en el que se encuentra el componente.

Habiendo hecho la transición de una aplicación más grande a NgModules recientemente, creo que en su mayoría son algo bueno (ahora que terminé con eso, tiene cierto sentido). De hecho, creo que el principal problema es que requieren una estructura de componentes diferente, algo que probablemente no encajaba bien con la forma en que estructuraste tu aplicación antes (al menos ese fue mi caso).

Sin embargo, siento que no deberían existir como la única solución. Si observa cómo se construyen comúnmente los componentes, entonces se dará cuenta de que, muy a menudo, se componen de subcomponentes más pequeños altamente especializados. Para estos subcomponentes, que no tienen ningún propósito fuera de ese componente contenedor, tener que mantenerlos en el módulo de alcance superior es realmente tedioso y puede dar lugar rápidamente a problemas de alcance.

Realmente apreciaría si hubiera un mecanismo _además_ de NgModules que permitiera a los componentes definir otros componentes o directivas como dependencias de alcance local que solo se aplican dentro de ese componente exacto (al igual que la lista directives funcionaba antes de los módulos).

Me gusta la sugerencia de @poke de tener una alternativa para aquellos que prefieren no ir a Full NgModules.

NgModules se agregaron en RC5 para resolver problemas con la compilación y la carga diferida, por lo que apenas forman parte del plan maestro original, por lo que no son ideales para algunos casos de uso (especialmente si estaba creando una aplicación basada en el diseño original "los componentes son rey").

Por supuesto, arreglan o habilitan algunas cosas, pero también traen sus propias complicaciones: más cosas para que las personas aprendan y diseñen, lo que es especialmente desafiante cuando aún no se han resuelto todas las mejores prácticas y enfoques. La adopción temprana puede traer mucho dolor, lo aprendí del viaje a RC4.

Me gustó más el plan original centrado en los componentes, lo que probablemente sea la razón por la que encuentro que Polymer / Web Components encaja mejor ahora. Los módulos se sienten como medio paso atrás a Angular 1.

Al principio me resistí a este cambio de eliminar tuberías y directivas, pero ahora me estoy acostumbrando y no parece tan malo como pensé al principio.

¿Alguien puede mostrarme cómo funciona NgModules en una aplicación realmente compleja donde varios componentes requieren varios otros en varios niveles? Todos los tutoriales, ejemplos y repositorios que vi solo muestran las formas fáciles en las que un módulo encapsula sus propios productos y publica (exporta) algunos de ellos a otros.

En proyectos reales, hay muchas dependencias cruzadas, generalmente con una cadena jerárquica. De alguna manera es falso probar un concepto de algo mediante un ejemplo designado exactamente para eso.

@para todos los autores de Angular2: ¿puede decirnos honestamente cuáles son las partes negativas de NgModules? Sé que puedes escribir un libro sobre todas las cosas buenas. Está bien. Pero siempre necesito lidiar con las cosas malas ocultas que no se aclararían si no hablas de ellas.

¿Alguien puede mostrarme cómo funciona NgModules en una aplicación realmente compleja donde varios componentes requieren varios otros en varios niveles?

Una forma de hacer esto sería crear un módulo de dependencia solo para esos componentes: Supongamos que tiene tres conjuntos de componentes A , B y C que contienen varios componentes todos y cada conjunto tiene los que están algo relacionados. Entonces estos tres conjuntos funcionarían bien para tres módulos separados.

Ahora, los componentes de cada uno de esos conjuntos requieren múltiples componentes de un conjunto D . Esos componentes en D solo se usan para los componentes en esos tres conjuntos. Dado que se usan en todos ellos, no puede simplemente agregar los componentes a esos módulos (ya que los componentes solo pueden ser parte de un solo módulo). En este punto, podría fusionar A , B , C y D en un módulo gigantesco, por lo que todas las dependencias están ahí. Pero eso es, por supuesto, muy desordenado. En su lugar, simplemente crea un nuevo módulo para D que solo contiene esas dependencias. Este módulo no hace nada más que proporcionar acceso a esos módulos. Ahora puede importar ese módulo en cada uno de esos otros tres módulos y puede usar los componentes. Pero debido a que los componentes aún son "privados", no reexporta el módulo ni importa el módulo D en algún otro módulo.

Dado que las importaciones de módulos solo afectan al módulo en sí, esto permite algún tipo de alcance sin contaminar otros módulos. Por supuesto, requiere que crees más módulos, pero así es como funciona.

Puedo compartir mi configuración actual. He usado 3 módulos en la aplicación: CommonModule, AppModule y TestModule.

  • CommonModule importa y exporta las cosas más comunes como HttpModule, FormsModule, MdInputModule, etc.
  • AppModule importa BrowserModule, CommonModule, app.routing y componentes individuales
  • TestModule importa y exporta BaseModule, pero sobrescribe algunos proveedores, como XHRBackend con MockBackend

He introducido esta configuración para simplificar TestBed.configureTestingModule,
así que tengo que importar TestModule y luego solo un componente como:

TestBed.configureTestingModule({
  imports: [ TestModule ],
  declarations: [ MyFormComponent ]
});

Una desventaja adicional que se hizo evidente cuando migré de RC-4 al lanzamiento fue que NgModules impone una fuerte penalización por refactorizaciones simples donde un componente simplemente necesita dividirse. Con NgModules, debe cambiar el módulo contenedor, que puede estar varios niveles por encima del árbol de componentes conceptuales, o promocionar el componente envolviéndolo en un NgModule y luego eliminándolo de su NgModule principal. La refactorización de componentes es esencial.

Esto está directamente relacionado con el punto de @poke

Realmente agradecería si hubiera un mecanismo además de NgModules que permitiera a los componentes definir otros componentes o directivas como dependencias de alcance local que solo se aplican dentro de ese componente exacto (al igual que la lista de directivas funcionaba antes que los módulos).

Estoy totalmente en desacuerdo. Una arquitectura modular como la propuesta por Angular 2 es más fácil de escalar, ajustar y refactorizar cuando sea necesario. Claro, de RC4 a RC5 hubo un poco de ajuste, pero en todo caso, para mí, NgModules ha demostrado permitir una aplicación mucho más flexible.

Angular es obstinado y ciertamente puede que no sea una talla única para todos, pero NgModules ciertamente no es el punto de falla para diseñar una aplicación inteligente, moderna y de alto rendimiento.

@emilio-martinez: En mi opinión, NgModule nunca se presentaría, si Angular 2 no fuera tan lento en el arranque, cuando se trata de JiT. Todas las demás 'mejoras' como 'escala, ajuste y refactorización' son discutibles, como muestra esta discusión.

Ha pasado bastante tiempo y muchos de nosotros hemos tenido tiempo de absorber completamente NgModule en nuestro trabajo. Creo que ahora está claro que, como algunas personas han descrito, una vez que pasa el bache de pasar al nuevo sistema de módulos, permite algunas cosas bastante buenas. Para cualquiera que siga este hilo y tenga problemas para absorber NgModule, sugiero que se desplace hasta el final y lea todo, especialmente de @robwormald y @wardbell .

Creo que todos encontraremos dentro de un año que muchas aplicaciones Angular 2+ hacen un uso generalizado y sin problemas de módulos, carga diferida y AOT. Creo que será completamente rutinario para la mayoría o casi todas las aplicaciones usar estas cosas para implementar la visión de "aplicación progresiva" en la que incluso las aplicaciones grandes y complejas tienen un tiempo de carga inicial casi instantáneo y luego cargan perezosamente (o precargan con pereza optimista) la funcionalidad que necesitar. El resultado es en realidad bastante ingenioso y se logra a un costo notablemente bajo para el desarrollador de la aplicación individual: NgModule básicamente es ese costo, y es una transición irritante, pero solo una cantidad muy modesta de trabajo en curso para usar.

@kylecordes Espero que tengas razón y creo que esa es la actitud correcta que debes tener.

@iurii-kyrylenko eso es muy cierto.

Tengo un problema con la compilación angular de mi JavaScript, ya que se supone que TypeScript compila mi JavaScript, pero ese es un problema aparte.

@kylecordes Creo que hay mucho más que considerar que solo la transición. Los módulos introducen mucha complejidad y muchas posibilidades adicionales para agregar errores a la propia aplicación. El mayor problema es la ofuscación de las dependencias. Lo que causará muchos problemas en los próximos años de desarrollo con angular 2.

@aluanhaddad Creo que Angular usa un contenedor tsc para compilar. Es bueno porque incluso puede implementarlo en un flujo de trabajo de ejecución de tareas, por ejemplo.

La velocidad de arranque de @ iurii-kyrylenko también es difícil de determinar en función de RC4. Gran parte del trabajo que se realizó desde entonces hasta el lanzamiento final ha sido la limpieza y las optimizaciones. En mi experiencia, Angular compilado JIT se ejecuta más rápido que RC4 de todos modos.

@DaSchTour , ¿puede dar más detalles sobre los errores que ha encontrado mientras trabajaba con NgModule?

@emilio-martinez no son errores en NgModule, sino errores que surgirán debido a importaciones faltantes o instancias de servicio duplicadas que se habrían omitido o encontrado en una etapa anterior de desarrollo. Se trata de importar cosas en el lugar donde las uso y no en un lugar donde no veo si se necesita o se usa y en qué lugar se necesita y se usa.

Solo piense en TypeScript trabajando de esta manera. Tengo un archivo base para mi módulo, llamémoslo _index.ts_ se ve así.

import {foo} from bar;
import {StartComp} from start;

StartComp.boot();

Entonces tenemos un archivo llamado start.ts que se parece a esto.

export class StartComp {
   public static boot() {
      foo()
   }
}

Eso es lo que está haciendo Angular con NgModules. Con un poco de magia he importado algo a un módulo y aparece en el otro extremo de mi aplicación. Debe saber que foo se importa en index.ts y al ejecutar StartComp desde el índice, las importaciones se pueden usar en el componente.

Las dependencias están ocultas y necesitan una investigación adicional para encontrarlas.

@emilio-martinez

En mi experiencia, Angular compilado JIT se ejecuta más rápido que RC4 de todos modos.

Tengo un proyecto de mediana complejidad, basado en MEAN stack y Angular 2 final. Se tarda unos 10 segundos en completar el arranque en modo JIT en mi dispositivo Android. Considero esto como un retraso significativo. Actualmente no puedo usar la compilación AOT sin modificar mi código fuente (problemas con miembros privados, operador elvis...).

¿Alguien tiene información sobre el rendimiento AOT + carga diferida para proyectos de la vida real?

Creo que Angular usa un contenedor tsc para compilar. Es bueno porque incluso puede implementarlo en un flujo de trabajo de ejecución de tareas, por ejemplo.

@emilio-martinez esto es exactamente lo que no quiero. Quiero compilar mi código usando cualquier versión de TypeScript que me plazca, por ejemplo, 2.1.0-dev que tiene emisión de nivel bajo para async/await. No quiero que Angular se encargue de compilar mis archivos TypeScript, esto no debe delegarse a un marco, es el rol de un lenguaje. Sin desviarme más del tema, no habría tocado @Script con un poste de diez pies, gracias a Dios que está muerto.
En cuanto al flujo de trabajo, uso JSPM y, a veces, Webpack, no un ejecutor de tareas tradicional, y dejo que mi IDE maneje mis linters.

Otro problema es que he escrito decoradores que se abstraen sobre decoradores angulares y ahora entiendo que muchos los ignorarán. Teniendo en cuenta lo pesados ​​​​que son los decoradores angulares, me decepcionó mucho saber que el marco no admitiría completamente a los decoradores, tratándolos, durante AOT, como anotaciones estáticas cuando, de hecho, son una construcción de tiempo de ejecución en el lenguaje subyacente.

@aluanhaddad es importante comprender que se producen dos pasos distintos durante la compilación de AoT: el primero es generar _nuevo_ código mecanografiado, el segundo es transpilar ese código a ES5/6. ngc hace ambas cosas por conveniencia, pero no hay nada inherente en AoT que requiera eso. Dentro de Google, hacemos ambas cosas, por lo que ese caso es la prioridad. Cualquiera podría implementar un host compilador para admitir la generación de código en cualquier entorno que quisiera.

No admitimos (todavía) la abstracción sobre los decoradores integrados de angular, pero si quisiera usar algo como https://www.npmjs.com/package/core-decorators , estaría bien.

@iurii-kyrylenko sugiere que mire el discurso de apertura del primer día de AngularConnect, donde LucidCharts habló sobre su experiencia con AoT. Ver https://youtu.be/xQdV7q3e_2w?t=1411

En mi humilde opinión, el objetivo número 1 de todos debería ser la compilación AoT lo antes posible. El rendimiento es simplemente insuperable.

@robwormald No he mirado qué opciones están disponibles al llamar a ngc , por lo que es posible que esto ya esté cubierto. Creo que esas opciones podrían aliviar las preocupaciones como las expresadas aquí, si hacen obvio que NGC está cumpliendo con el primer propósito como su principal razón de existir en el segundo propósito como conveniencia/optimización. Si la documentación o la ayuda muestran cómo ejecutar por separado tsc listos para usar para aquellos que prefieren hacerlo, ¿eso podría aliviar aún más las preocupaciones?

@kylecordes , no creo que la documentación cubra cómo implementar su propio host compilador en el corto plazo. Es un caso de uso avanzado y, por lo tanto, requeriría un aprendizaje autodirigido para implementarlo. Implementamos algo similar para la CLI aquí https://github.com/angular/angular-cli/tree/master/packages/webpack

@robwormald Ah, no me refiero a implementar su propio host compilador. Solo quise decir un "proceso de compilación" de dos líneas: primero llamar a ngc para emitir un texto mecanografiado generado, luego llamar a tsc usted mismo para compilar todo el texto mecanografiado (su fuente más la fuente generada) para JavaScript. Esto proporciona una garantía rápida de que el código TypeScript simplemente se está compilando en JS mediante el compilador de TypeScript disponible en el mercado.

@robwormald Gracias por su respuesta.
Con respecto a NGC, lo que quiero saber es si puedo controlar la versión y la configuración del compilador de TypeScript en el paso TS -> TS . ¿Puedo pasar TypeScript a NGC o tengo que usar una versión específica que envuelva una versión específica de TypeScript? ¿Qué tan acoplados están?

Con respecto a los decoradores, ¿hay algún problema de soporte de seguimiento para los decoradores definidos por el usuario que se abstraen sobre los decoradores angulares? El https://www.npmjs.com/package/core-decorators es un conjunto ortogonal de decoradores, pero tengo decoradores que imponen patrones y convenciones en mis aplicaciones angulares envolviendo decoradores angulares. Un caso de uso obvio para esto es crear y aplicar automáticamente prefijos de nombres de componentes en todo el paquete, pero también hay otros.

Dado que NGC no admite esto, ¿cómo sabe qué decoradores son específicos de Angular?
¿Coincide con los decoradores angulares por nombre?
Espero que no porque eso violaría el alcance léxico de JavaScript.
Un escenario sencillo
_awesome-component-decorators.ts_

import { Component } from '@angular/core';
import template from './awesome-component.html';
import style from './awesome-component.less';

export const awesomeComponet = <T extends new (...args) => any>(target: T) =>
  Component({template, styles: [style], selector: snakeCase(target.name) })(target);

_consumidor.ts_

import { awesomeComponet } 'app/shared/awesome-component-decorators';

<strong i="19">@awesomeComponent</strong> 
export class AnAwesomeComponent { }

<strong i="20">@awesomeComponent</strong> 
export class AnotherAwesomeComponent { }

@jpsfs ¿Ha encontrado alguna solución para cargar componentes dinámicamente sin agregar declaraciones de componentes al módulo de aplicación raíz? .

También soy parte de un proyecto de migración angular 1.X a Angular 4. Este proyecto tiene una gran cantidad de componentes que se reutilizan en diferentes aplicaciones que se cargan de forma diferida según el contexto de la aplicación.

Según mi entendimiento en Angular 4

Tenemos que agregar dependencias de componentes en las declaraciones raíz @NgModule como se muestra a continuación.

importar {platformBrowserDynamic} desde "@angular/platform-browser-dynamic";
importar {Componente, NgModule} desde "@angular/core";
...
...
@MóduloNg({
imports: [BrowserModule], // importa el módulo de navegador de Angular
bootstrap: [BootStrapComp], // indica el componente bootstrap
declaraciones: [com1, comp2 , comp5 ...... Comp n ] // registramos nuestro componente con el módulo
})
clase de exportación AppModule {}

plataformaBrowserDynamic().bootstrapModule(AppModule);

Pero en nuestro caso, no queríamos rootear NgModule para conocer las dependencias de los componentes en tiempo de compilación. Más bien, queríamos que los componentes se cargaran dinámicamente en tiempo de ejecución.
¿Encontró alguna buena solución que pueda iniciar la aplicación sin agregar todos los componentes en las declaraciones raíz de NgModule (y tampoco queríamos tener un NgModule para cada componente :))

@DaSchTour

¿Recuerda las veces que el punto de entrada de su aplicación se veía así?

Bueno, para eso, algunos de nosotros usamos scripts de compilación para requerir automáticamente estos módulos y agregarlos al módulo de la aplicación.

Estoy buscando algo similar y una solución fácil en angular2.

@samudrak , no puede cargar de forma diferida solo el componente si desea utilizar el soporte Angular aot. Deberá configurar el módulo diferido para cada componente y cargar el módulo de forma diferida. Usamos un enfoque similar en nuestra aplicación...

Con soporte de importaciones dinámicas en ECMAScript y ahora en TypeScript (con verificación de tipo completa ortogonal a la carga), el caso de uso de carga diferida es bastante arbitrario. Por supuesto, la retrospectiva es 20/20 y no había forma de saber que eso sucedería.

Este problema se ha bloqueado automáticamente debido a la inactividad.
Presente un nuevo problema si encuentra un problema similar o relacionado.

Obtenga más información sobre nuestra política de bloqueo automático de conversaciones .

_Esta acción ha sido realizada automáticamente por un bot._

¿Fue útil esta página
0 / 5 - 0 calificaciones