binding - navigationend - router events subscribe angular 4
Salida angular 2 desde la salida del enrutador (4)
Cambié un poco de la respuesta de Antara Datta. Creé un servicio de suscriptor
import {Injectable} from ''@angular/core'';
import {Subject} from ''rxjs'';
@Injectable({
providedIn: ''root''
})
export class Subscriber<T>
{
protected observable = new Subject<T>();
public next(item: T)
{
this.observable.next(item);
}
public subscribe(callback: (item:T)=>void) {
this.observable.subscribe(callback);
}
}
Cada vez que necesito dos componentes para compartir información, inyecto este servicio en el constructor que se suscribe a él:
constructor(protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
{
layoutOptions.subscribe(options => this.options = Object.assign({}, this.options, options));
}
y el que lo actualiza
constructor(protected router: Router, protected apiService: ApiService, protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
{
this.layoutOptions.next({showNavBar: false});
}
Quiero hacer la navegación desde componentes secundarios que se procesan dentro de la salida del enrutador. Mi componente principal tiene una configuración de enrutador y quiero navegar manualmente en algún evento. Pero no sé cómo puedo pasar de niño a padre algunos datos (para la navegación) sin salida. Porque esta construcción no funciona
<router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet>
¿Cómo puedo hacerlo de la manera correcta? Tal vez navegar desde niño? Pero cómo puedo obtener métodos para padres de niño. ¡Muchas gracias por cualquier ayuda!
La respuesta dada anteriormente es correcta y completa. Solo quiero agregar para aquellos a quienes la solución no les funcionó, que deberían agregar el servicio a los proveedores solo en el componente principal y no en el secundario para garantizar que obtengan un singleton del servicio; de lo contrario, dos instancias de servicio serán creado. Esta respuesta está inspirada en el comentario de @HeisenBerg en la respuesta anterior.
<router-outlet></router-outlet>
es solo un marcador de posición para agregar componentes enrutados.
No hay soporte para ningún tipo de enlace.
Puede crear un
<router-outlet>
que le permita hacer eso o, lo que es más común, usar un servicio compartido para comunicarse entre el componente principal y el componente enrutado.
Para más detalles ver https://angular.io/docs/ts/latest/cookbook/component-communication.html
actualizar
Ahora hay un evento que permite obtener el componente agregado
<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>
que permite comunicarse (captadores de llamadas, establecedores y métodos) con el componente en
componentAdded()
Sin embargo, un servicio compartido es la forma preferida.
<router-outlet></router-outlet>
no se puede utilizar para emitir un evento desde el componente hijo.
Una forma de comunicarse entre dos componentes es utilizar un servicio común.
Crea un servicio
shared-service.ts
import { Observable } from ''rxjs/Observable'';
import { Injectable } from ''@angular/core'';
import { Subject } from ''rxjs/Subject'';
@Injectable()
export class SharedService {
// Observable string sources
private emitChangeSource = new Subject<any>();
// Observable string streams
changeEmitted$ = this.emitChangeSource.asObservable();
// Service message commands
emitChange(change: any) {
this.emitChangeSource.next(change);
}
}
Ahora inyecte la instancia del servicio anterior en el constructor del componente primario y secundario.
El componente hijo emitirá un cambio cada vez que se llame al método onClick ()
child.component.ts
import { Component} from ''@angular/core'';
@Component({
templateUrl: ''child.html'',
styleUrls: [''child.scss'']
})
export class ChildComponent {
constructor(
private _sharedService: SharedService
) { }
onClick(){
this._sharedService.emitChange(''Data from child'');
}
}
El componente principal recibirá ese cambio. Para hacerlo, capture la suscripción dentro del constructor del padre.
parent.component.ts
import { Component} from ''@angular/core'';
@Component({
templateUrl: ''parent.html'',
styleUrls: [''parent.scss'']
})
export class ParentComponent {
constructor(
private _sharedService: SharedService
) {
_sharedService.changeEmitted$.subscribe(
text => {
console.log(text);
});
}
}
Espero que esto ayude :)