Angular 2 salida de router-outlet
Quiero hacer la navegación desde componentes secundarios que se renderizan dentro del router-outlet. Mi componente padre tiene una configuración de enrutador y quiero navegar manualmente en algún evento. Pero no se como puedo pasar de niño a padre algunos datos (para 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 el niño? Pero cómo puedo obtener métodos de padres de niño. Muchas gracias por cualquier ayuda!
4 answers
<router-outlet></router-outlet>
es solo un marcador de posición para agregar componentes enrutados. No hay soporte para ningún tipo de unión.
Puede crear un <router-outlet>
personalizado que le permita hacer eso o más común, usar un servicio compartido para comunicarse entre el componente padre y el componente enrutado.
Para más detalles ver https://angular.io/docs/ts/latest/cookbook/component-communication.html
Update
Ahora Hay un evento que permite obtener el añadido componente
<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>
Que permite comunicarse (getters de llamadas, setters y métodos) con el componente en componentAdded()
Sin embargo, un servicio compartido es la forma preferida.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-28 03:28:20
<router-outlet></router-outlet>
no se puede usar para emitir un evento desde el componente hijo. Una forma de comunicarse entre dos componentes es utilizar un servicio común.
Crear un servicio
Servicio compartido.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 padre e hijo.
El componente hijo emitirá un cambio cada vez que se llame al método onClick ()
Niño.componente.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 ello,captura la suscripción dentro del constructor del padre.
Padre.componente.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:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-24 06:50:40
La respuesta dada arriba es correcta y completa. Solo quiero agregar para aquellos que la solución no funcionó para ellos que deben agregar el servicio a los proveedores solo en el componente padre y no en el hijo para asegurarse de que obtenga un singleton del servicio, de lo contrario se crearán dos instancias de servicio. Esta respuesta está inspirada en el comentario de @HeisenBerg en la respuesta anterior.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-24 06:35:19
Cambié un poco de la respuesta de Antara Datta. He creado un servicio de abonado
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 alguna 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});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-02 19:55:45