template tablas formularios example dinamicas angular angular6

formularios - tablas angular 4



¿Hay una manera de agregar una aserción/anotación de tipo a una variable de entrada de plantilla? (5)

¡Vamos a ver qué angular tiene algo similar y cómo funciona!

<p *ngFor="let number of [{v: 101},{v: 102}, {v: 103}]">{{number.v}}</p>

Podemos reescribirlo sin * magia.

<ng-template ngFor let-number [ngForOf]="[{v: 101},{v: 102}, {v: 103}]"> <p>{{number.v}}</p> </ng-template>

Sin observadores (ngDoCheck) puede ser el mismo que (pero ngTemplateOutlet no tiene verificación de tipo ):

<ng-template let-number #templateRef> <p>{{number.v}}</p> </ng-template> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 101}}"></ng-container> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 102}}"></ng-container> <ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 103}}"></ng-container>

O podemos crearlo por nosotros mismos.

// template <button (click)=create(templateRef)>create</button> // TS constructor(private _viewContainerRef: ViewContainerRef) { } create(templateRef: TemplateRef<{$implicit: {v: number;}}>) { this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 101}}); this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 102}}); this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 103}}); }

TL; DR

La magia de comprobación de plantillas de plantilla ocurre dentro de viewContainerRef.createEmbeddedView . (por ejemplo ngFor ); Pero asume lo que acepta templateRef.

Angular se puede compilar en AOT:

<p *ngFor="let num of [{v:1}, {v:2}]"> {{num.does.not.exist.completly}} </p>

Entonces, como entendí, deberíamos asumir qué tipos de plantillas tienen pero verificar cuándo se createEmbeddedView instancia de la plantilla (mediante createEmbeddedView );

Fondo

Tengo una plantilla que se parece a esto (estoy usando algún componente que usa esto como base para un elemento repetido, es la p-pickList, pero la pregunta no es específica sobre ese componente, solo como un ejemplo)

Para el fondo, digamos que tengo un tipo Foo y mi componente tiene un foos: Foo[] , lo estoy <p-pickList> componente <p-pickList> bajo el atributo [source] y está haciendo el *ngFor interno para ello, todo lo que tengo que hacer es proporcionar una plantilla

<ng-template let-foo pTemplate="item"> ... {{ foo.anythingGoesHereWithNoWarningAndNoAutocomplete }}

Sin embargo, la información de tipo en foo parece estar perdida.

Soy un gran fan de la seguridad de tipos y me gusta que Intellij (o cualquier otro editor) pueda mostrarme una advertencia si dentro de la plantilla hago algo como especificar un atributo no válido de foo

Si tuviera un *ngFor regular, *ngFor el tipo de foo

<div *ngFor="let foo of foos"> {{ foo.autoCompleteWorksInMostIDEsAsWellAsWarningIfInvalidProp }}

Preguntas:

  1. ¿Hay alguna sintaxis que me permita insinuar el tipo de let-foo ? (y esperamos que la mayoría de los IDEs lo reconozcan).

  2. Si no quiero confiar en IDE, ¿hay alguna forma de que el tipo de compilador ng verifique foo (declarado por let-foo)?

tl; dr ¿hay una sintaxis que me permita escribir y anotar la variable de entrada de la plantilla? por ejemplo, algo como esto se compone sintaxis?

let-foo="$implicit as Foo" o let-foo-type="Foo" ?

Solución

Una idea tonta es tener una función de identidad en mi componente, por ejemplo,

identity(foo: Foo): Foo { return foo; }

pero haciendo

{{ identity(foo).fooProp }}

No es una gran mejora sobre

{{ (foo as Foo).fooProp }}


El problema es que no hay ningún tipo de información. <ng-template let-foo pTemplate="item"> - es solo una declaración de plantilla, aún no está enlazado a ningún tipo / contexto, solo un tipo dinámico que tiene o puede tener anythingGoesHereWithNoWarningAndNoAutocomplete campo anythingGoesHereWithNoWarningAndNoAutocomplete . Sin el apoyo genérico adecuado no es posible tener este tipo de seguridad de tipos.


Encontré este problema y la solución propuesta para permitir que las variables de entrada de la plantilla publiquen información de tipo para que los IDE puedan proporcionar una mejor terminación en github here . Esta característica se encuentra actualmente en desarrollo y es de esperar que salga a la venta en el futuro de Angular. Debes usar la extensión del marketplace.visualstudio.com/items?itemName=Angular.ng-template en el Código VS o Texto Sublime por ahora. Puede estar seguro del soporte de la extensión porque el equipo de Angular está trabajando en ello. Para obtener más información, consulte este readme y documentos .

Como mencionó, se puede lograr mediante el uso de la función de identidad, pero causará un gran problema de rendimiento y será un desastre mantener esta funcionalidad para diferentes tipos.


Usar Interfaces puede lograr el comportamiento que mencionas:

En el archivo ts, defina una interfaz:

export interface Dog { name: string; age: number; }

en el componente define la variable:

@Component()...{ ... mrSnuggles: Dog = { name: ''mrSnuggles'', age: 10 }; }

y en la plantilla:

{{mrSnuggles.food}}

Se puede ver el error (intelecto idea):