page - Angular 2-¿Cómo escuchar un evento sin una plantilla?
router events angular 6 (1)
El problema
Normalmente, en Angular 2, uno escucharía un evento a través de la siguiente sintaxis:
<my-elem (customEvent)="customEventProcessor"></my-elem>
Pero cuando uso un enrutador, ese host, <my-elem>
, no existe en ninguna plantilla. En su lugar, hay un <router-outlet>
, y mi componente se carga en la navegación. Por lo tanto, el quid de mi problema es, ¿cómo puedo forzar a mi anfitrión a escuchar mi evento personalizado sin depender de una plantilla?
Detalles opcionales
Supongamos que tengo una list-view
elementos, que es un elemento secundario de mi componente raíz. list-view
escucha un evento personalizado a través de la sintaxis normal:
<list-view (customEvent)="customEventProcessor()"></list-view>
Solo para estar completo, el componente de list-view
que emite el evento también tiene una estructura predecible:
<button (click)="onDetailsClick(propertyOfInterest)">Click here</button>
La list-view
envía el evento al padre mediante observación.
class ListView {
...
public onDetailsClick(property: string): void {
this.customEvent.next({ value: property });
}
}
y ese evento activa la función customEventProcessor()
. Hasta ahora tan bueno. Sin embargo, cuando uso un enrutador para controlar si list-view
está presente, no puedo (a mi entender) insertar un comando para monitorear algún evento.
No estoy seguro de cuál es el mejor enfoque para manejar este caso.
Este problema aún no se ha resuelto (consulte este tema de github ). Aquí está una de las posibles soluciones en este momento (vea este plunk ):
@Component({
selector: ''my-app'',
directives: [RouterOutlet, RouterLink],
template: `
<h1>{{ message }}</h1>
<a [router-link]="[''./MyElem1'']">MyElem1</a>
<a [router-link]="[''./MyElem2'']">MyElem2</a>
<router-outlet></router-outlet>
`
})
@RouteConfig([
{ path: ''/'', redirectTo: ''/my-elem1'' },
{ path: ''/my-elem1'', name: ''MyElem1'', component: MyElem1 },
{ path: ''/my-elem2'', name: ''MyElem2'', component: MyElem2 },
])
export class App {
message: string = ''Click on the button'';
@ViewChild(MyElem1) myElem1: MyElem1;
@ViewChild(MyElem2) myElem2: MyElem2;
constructor(router: Router) {
let subs = null;
router.subscribe(() => {
if (subs) { subs.unsubscribe(); subs = null; }
if (this.myElem1) {
subs = this.myElem1.customEvent1.subscribe(m=>this.processCustomEvent(m));
}
if (this.myElem2) {
subs = this.myElem2.customEvent2.subscribe(m=>this.processCustomEvent(m));
}
});
}
processCustomEvent(message) { this.message = message }
}