2016-06-06 4 views
23

Я хочу сделать навигацию от дочерних компонентов, которые отображают внутри маршрутизатора. У моего родительского компонента есть конфигурация маршрутизатора, и я хочу вручную перемещаться по некоторому событию. Но я не знаю, как я могу передать от ребенка к родителям некоторые данные (для навигации) без вывода. Поскольку эта конструкция не работаетУгловой выход 2 с выхода маршрутизатора

<router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet> 

Как я могу это сделать правильно? Может быть, переместите его от ребенка? Но как я могу получить родительские методы от ребенка. Большое спасибо за помощь!

ответ

25

<router-outlet></router-outlet> является просто заполнителем для добавления маршрутизированных компонентов. Нет никакой поддержки для каких-либо привязок.

Вы можете создать пользовательский <router-outlet>, который позволит вам сделать это или более распространенным, использовать совместно используемую службу для связи между родительским компонентом и маршрутизируемым компонентом.

Для получения дополнительной информации см https://angular.io/docs/ts/latest/cookbook/component-communication.html

обновление

Существует в настоящем событие, которое позволяет получить Добавленный компонент

<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet> 

, которая позволяет общаться (добытчики вызовов, сеттера, и методы) с компонентом в componentAdded()

A sh Однако сервис isd является предпочтительным.

+0

Можете ли вы подробнее рассказать о том, почему общий сервис является предпочтительным? –

+0

Поскольку нет другого хорошего способа, и разделяемая услуга является предпочтительным способом для общения между компонентами, которые не являются прямым родительским-ребенком в целом. –

60

<router-outlet></router-outlet> не может использоваться для испускания события из дочернего компонента. Один из способов общения между двумя компонентами - использовать общую службу.

Создание службы

разделяемой 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); 
    } 
} 

Теперь впрыскивать экземпляр указанного выше сервиса в конструкторе как родителя и компонента ребенка.

Компонент ребенок будет излучать изменение каждый раз, когда метод 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'); 

} 
} 

Родительский компонент должен получить это изменение. Для этого запишите подписку внутри конструктора родителя.

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); 
     }); 
     } 

} 

Надеюсь, это поможет :)

+0

Не могли бы вы показать, как вы могли бы использовать «текст» в шаблоне родительского компонента? :) –

+0

@AndrewJuniorHoward, вы можете просто назначить его локальной переменной. Например: класс экспорта ParentComponent { dummyText: string; конструктор ( частный _sharedService: SharedService ) { _sharedService.changeEmitted $ .subscribe ( текст => { this.dummyText = текст; }); } } –

+0

Отличный ответ, но я хочу выделить одну маленькую вещь: если мы не отменим подписку changeEmitted $ после уничтожения компонента, это будет выдавать больше времени, а затем после того, как мы вернемся в этом компоненте –

1

Ответ приведенный выше правильный и полный.Я просто хочу добавить для тех, у кого решение не сработало для них, чтобы они добавляли эту услугу поставщикам только в родительский компонент, а не в дочерний элемент, чтобы убедиться, что вы получаете одноэлемент службы, иначе два экземпляра службы будут создано. Этот ответ вдохновлен комментарием @HeisenBerg в предыдущем ответе.

Смежные вопросы