Как вызвать дочерний компонент выходного роутера от родительского компонента
Я новичок в angular2
<parent>
<router outlet><router outlet>
</parent>
У меня есть кнопка в родительском компоненте, если я нажму на эту кнопку, она должна вызывать метод в дочернем компоненте (который загружается в розетку маршрутизатора).
Есть ли способ вызова метода дочернего компонента (в роутере) из родителя.
Ответы
Ответ 1
Существует два способа отображения шаблона компонента: как вложенный компонент или как цель маршрутизации.
Вложенный компонент
Если вы используете вложенный компонент, то считается, что компоненты имеют отношение "родительский компонент/дочерний компонент".
Html для родительского компонента будет выглядеть следующим образом:
<div>
<child></child>
</div>
Где "ребенок" - это селектор дочернего компонента. Затем вы можете обмениваться данными между ними с помощью свойств @Input и @Output.
Для получения дополнительной информации об этом методе, когда у вас есть вложенные компоненты, ознакомьтесь с документами здесь: https://angular.io/guide/component-interaction
Цель маршрутизации
Если вы используете компонент как цель маршрутизации, отображая его в <router-outlet>
, тогда нет отношения "родительский компонент" и "дочерний компонент".
Лучшим способом связи между компонентами в этом случае является использование службы.
У меня есть сообщение в блоге о создании сервиса здесь: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/
Ресурсы
Если вы новичок в Angular, вы можете сохранить себе кучу времени и разочарований, работая через учебник или онлайн-курс. Это приведет к появлению всех основных понятий, которые помогут вам быстро с Angular.
Вы можете поупражняться в учебнике "Tour of Heroes": https://angular.io/tutorial
Или просмотрите такой курс, как этот: https://app.pluralsight.com/library/courses/angular-2-getting-started-update
Или этот: https://app.pluralsight.com/library/courses/angular-2-first-look/table-of-contents
(Вы можете подписаться на бесплатную неделю.)
Ответ 2
Я нашел два способа добиться этого:
1. Ввод основного компонента в дочерние
Вы можете добавить событие в свой основной компонент, вставить основной компонент в дочерние компоненты и подписаться на это событие. См. plunk, который иллюстрирует это. Но теперь у ваших детей есть зависимость от вашего основного компонента. Это может быть плохо.
основной компонент
executeAction: EventEmitter<any> = new EventEmitter();
constructor() { }
performAction() {
this.executeAction.emit();
}
ребенок
constructor(private appComponent: AppComponent) {
this.executeAction = this.executeAction.bind(this);
eventSubscriber(appComponent.executeAction, this.executeAction);
}
ngOnDestroy(): void {
eventSubscriber(this.appComponent.executeAction, this.executeAction, true);
}
executeAction() {
alert('1');
}
2. Внедрение службы
Лучшее решение здесь и как описано в Родитель и дети обмениваются данными через службу - это создание службы, которая будет дополнительным уровнем между основного компонента и детей. Таким образом, вы будете независимы от реализации основного компонента. См. plunk, который иллюстрирует этот подход.
услуги
subscription = new Subject();
executeAction() {
this.subscription.next();
}
основной компонент
constructor(private appService: AppService) { }
performAction() {
this.appService.executeAction();
}
ребенок
constructor(private appService: AppService) {
this.executeAction = this.executeAction.bind(this);
eventSubscriber(appService.subscription, this.executeAction);
}
ngOnDestroy(): void {
eventSubscriber(this.appService.subscription, this.executeAction, true);
}
executeAction() {
alert('1');
}
Ответ 3
С дочерним элементом router-outlet
вы можете использовать ContentChild
для вызова метода в дочернем элементе. Так что...
import { ContentChild } from '@angular/core';
в вашем родителе:
@ContentChild(ChildComponent)
private childComponent: ChildComponent;
и в событии клика выполните:
this.childComponent.doSomething()
Также вам нужно добавить дочерний компонент в массив поставщиков в родительском:
@Component({
selector: 'parent',
...
providers: [ChildComponent]
})
Ответ 4
Я думаю, Источник событий может сделать трюк для вас
Хотя вы можете использовать его непосредственно в дочернем компоненте, но использование общей службы здесь будет хорошей практикой
Сначала вам нужно создать излучатель в сервисе, что-то вроде
export class EmitterService {
public nameEmitter:EventEmitter<string>=new EventEmitter();
//method to get question
changeName(name:string){
this.nameEmitter.emit(name)
}
}
Затем в корневом компоненте введите зависимость службы службы и метод имени изменения вызова, чтобы исправить изменение
constructor(private emitter :EmitterService) {}
this.emitter.changeName("New Name");
И в конце в дочернем компоненте подписаться на изменения
this.emitter.nameEmitter.subscribe(name=>{this.name=name})
Здесь работает plunker
Ответ 5
Вы можете использовать shared service для связи с компонентами, добавленными маршрутизатором.
Вы также можете использовать активировать событие в роутере для родителя, чтобы знать, когда компонент был добавленный маршрутизатором
Шаблон
<router-outlet (activate)="onActivate($event)"></router-outlet>
Компонент
onActivate(componentRef){
componentRef.works();
}
Ребенок
works(){
console.log("works");
}
Ответ 6
Существует два способа вызова дочернего компонента дочернего компонента роутера из родительского компонента.
-
ViewChild/ViewChildren - вы можете использовать ViewChild/ViewChildren для получения элементов или директив (ов), соответствующих селектору, из представления DOM. Не имеет значения, что дочерний компонент отображается через розетку маршрутизатора.
import {ViewChild} из '@angular/core';
@ViewChild (HomeComponent)
private childComponent: HomeComponent;
Затем вы можете вызвать любой метод,
this.childComponent.changeTitle();
Демонстрационный метод вызова дочернего компонента маршрутизатора роутера
- Общие службы. Поскольку службы angular являются одноточечными, введя их в свои контроллеры, вы можете вызывать методы. (Над ответами уже упоминался этот подход)