Как вызвать дочерний компонент выходного роутера от родительского компонента

Я новичок в 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();

Демонстрационный метод вызова дочернего компонента маршрутизатора роутера

  1. Общие службы. Поскольку службы angular являются одноточечными, введя их в свои контроллеры, вы можете вызывать методы. (Над ответами уже упоминался этот подход)