ejemplos - Angular2 y soporte de herencia de clase
angular wikipedia (2)
Agregue un proveedor a cada componente derivado, aliasing el componente base para el componente derivado:
@Component({
selector: ''child-comp2'',
template: ''<div>child component #2</div>'',
providers: [{provide: BaseComponent, useExisting: forwardRef(() => ChildComponent2) }]
})
export class ChildComponent2 extends BaseComponent {
}
@Component({
selector: ''child-comp1'',
template: ''<div>child component #1</div>'',
providers: [{provide: BaseComponent, useExisting: forwardRef(() => ChildComponent1) }]
})
export class ChildComponent1 extends BaseComponent {
}
Plunker: http://plnkr.co/edit/5gb5E4curAE2EfH2lNZQ?p=preview
Estoy construyendo una aplicación Angular2 en Typescript y me gustaría utilizar la funcionalidad del sistema de clase (leer: herencia de clase) que ofrece Typescript. Sin embargo, parece que Angular2 no está jugando bien con las clases derivadas. Estoy buscando ayuda para hacer que mi aplicación funcione.
El problema al que me enfrento es que tengo una clase base y de allí obtengo algunas clases para niños. Cuando estoy construyendo mi árbol de componentes, me gustaría poder acceder a los padres / hijos de los componentes (de cualquier manera está bien). Por lo que entiendo, Angular2 ofrece dos opciones para lograr eso:
- Inyectar el elemento primario en el componente secundario
- Use ContentChildren (o ViewChildren) para acceder a los elementos secundarios del componente.
Ambos funcionan bien si conoce el tipo de la clase con la que está trabajando (ChildComponent), pero parecen fallar cuando intenta utilizar la clase base de estos componentes (BaseComponent) como selector.
Para visualizarlo en algún código (ver este Plunker para una demostración en vivo), tengo un componente / clase de aplicación de la siguiente manera:
@Component({
selector: ''my-app'',
template: `<parent-comp>
<child-comp1></child-comp1>
<child-comp1></child-comp1>
<child-comp2></child-comp2>
</parent-comp>`,
directives: [ParentComponent, ChildComponent1, ChildComponent2]
})
export class MyApplication {
}
La clase base y las clases secundarias se definen como:
export class BaseComponent {
// Interesting stuff here
}
@Component({
selector: ''child-comp2'',
template: ''<div>child component #2</div>''
})
export class ChildComponent2 extends BaseComponent {
}
@Component({
selector: ''child-comp1'',
template: ''<div>child component #1</div>''
})
export class ChildComponent1 extends BaseComponent {
}
Y la clase de Padres tiene cierta lógica para contar sus hijos.
@Component({
selector: ''parent-comp'',
template: `<div>Hello World</div>
<p>Number of Child Component 1 items: {{numComp1}}
<p>Number of Child Component 2 items: {{numComp2}}
<p>Number of Base Component items: {{numBase}}
<p><ng-content></ng-content>
`
})
export class ParentComponent implements AfterContentChecked {
@ContentChildren(ChildComponent1) contentChild1: QueryList<ChildComponent1>
@ContentChildren(ChildComponent2) contentChild2: QueryList<ChildComponent2>
@ContentChildren(BaseComponent) contentBase: QueryList<BaseComponent>
public numComp1:number
public numComp2:number
public numBase:number
ngAfterContentChecked() {
this.numComp1 = this.contentChild1.length
this.numComp2 = this.contentChild2.length
this.numBase = this.contentBase.length
}
(Nuevamente, puedes ver una demostración en vivo Plunker )
La salida de los primeros dos contadores es la esperada. Hay 2 hijos ChildComponent1 y 1 ChildComponent2. Desafortunadamente, el contador BaseComponent no muestra la suma de estos contadores, pero muestra 0. No encuentra ninguna clase que sea de tipo BaseComponent en los elementos secundarios.
Lo mismo sucede cuando ParentComponent también se extiende desde BaseComponent y desea Inyectarlo en un componente ChildComponent. El inyector requerirá el tipo específico de ParentComponent y no puede funcionar con la clase base.
¿Alguna pista sobre cómo trabajar con clases derivadas en Angular2? ¿Me estoy perdiendo algo o estoy intentando algo imposible?
Puede utilizar variables de plantilla locales con una consulta ContentChildren para crear una lista de todos los componentes con una clase base compartida. Aquí hay un plunk para el código a continuación. Este enfoque fue tomado de la sugerencia en la publicación de blog de errores de novato de Kara Erickson.
En la plantilla, cada componente secundario está marcado con #child :
<app-container>
<app-child1 #child></app-child1>
<app-child1 #child></app-child1>
<app-child1 #child></app-child1>
<app-child1 #child></app-child1>
<app-child2 #child></app-child2>
</app-container>
Esto se puede usar para seleccionar todos los componentes con el componente base compartido:
import { Component, QueryList, ContentChildren, ViewChildren, AfterViewInit, AfterContentInit } from ''@angular/core'';
import { BaseComponent } from ''../base/base.component'';
import { Child1Component } from ''../child1/child1.component'';
import { Child2Component } from ''../child2/child2.component'';
@Component({
selector: ''app-container'',
templateUrl: ''./src/container/container.component.html''
})
export class ContainerComponent implements AfterContentInit {
@ContentChildren(''child'') allChildren: QueryList<BaseComponent>;
@ContentChildren(Child1Component) child1Chdilren: QueryList<Child1Component>;
@ContentChildren(Child2Component) child2Chdilren: QueryList<Child2Component>;
constructor() { }
ngOnInit() {
}
ngAfterContentInit() {
}
}