Доступ к выходному компоненту маршрутизатора из родителя

У меня есть следующий корень приложения:

@Component({
    selector: 'my-app',
    providers: [],
    templateUrl: `<button (click)="callChildFunction()">Close</button>
                  <router-outlet></router-outlet>`
})
export class AppComponent {

    constructor() {

    }

    callChildFunction(){
        // Call myFunction() here
    }

}

А вот мой ребенок (компонент, используемый в router-outlet):

@Component({
    selector: 'child',
    providers: [],
    templateUrl: `<div>Hello World</div>`
})
export class ChildComponent {

    constructor() {

    }

    myFunction(){
        console.log('success');
    }

}

Я обнаружил, что могу использовать RouterOutlet для получения функций компонента, но он не кажется доступным из в корне приложения.

Как я могу вызвать myFunction() из корня приложения?


person ncohen    schedule 16.08.2017    source источник
comment
вы просто хотите вызвать дочернюю функцию в родительском компоненте?   -  person Rahul Singh    schedule 16.08.2017
comment
Точно... Я хотел бы получить (неизвестный) компонент, используемый в розетке маршрутизатора, и вызвать его функцию   -  person ncohen    schedule 16.08.2017
comment
если вы не знаете о компоненте, как вы можете вызвать метод, будет ли у всех компонентов общий метод?   -  person Rahul Singh    schedule 16.08.2017
comment
Да, у всех компонентов есть общий метод, который делает разные вещи в зависимости от компонента. Но название метода всегда одно и то же...   -  person ncohen    schedule 16.08.2017


Ответы (3)


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

Родительский компонент

  <div class="container">
    <router-outlet (activate)="onActivate($event)"></router-outlet>
  </div>

Шаблон

  onActivate(componentRef){
    componentRef.works();
  }

Композиция для детей

 works(){
    console.log("works");
  }
person Rahul Singh    schedule 16.08.2017
comment
но при начальной загрузке дочерний компонент не будет отображаться в DOM.... образец - stackblitz.com/edit/ - person Kumaresan Sd; 27.01.2020

Небольшое дополнение к отличному ответу @Rahul Singh:

Убедитесь, что вы проверяете, какой экземпляр компонента возвращается в методе
(оставаясь в примере Рахула) onActivate(componentRef),
и вызываете только works(), если этот компонент действительно имеет такой метод.

Пример:

     onActivate(componentRef){
       if(componentRef instanceof ChildWithWorksMethodComponent){
         componentRef.works();
         return;
         }
         console.log("This is not the ChildWithWorksMethodComponent");
      }  

В противном случае каждый раз, когда вы переходите к маршруту, компонент которого не имеет такого метода, ваш журнал консоли будет полон ошибок, таких как:

ОШИБКА TypeError: componentRef.works не является функцией

person Z3d4s    schedule 12.05.2019
comment
Кажется, что это работает для вызова функций в компоненте router-outlet, но, похоже, не позволяет получить доступ к properties, даже через getters и setters. Итак, невозможно получить доступ к данным/свойствам в компоненте router-outlet, или я что-то делаю не так? - person Crowdpleasr; 17.10.2019

Router-outlet связан с маршрутизацией, он не имеет ничего общего с доступом к методам дочернего компонента. Вы должны использовать @ViewChild для доступа к функциям дочернего компонента от родителя. Вы можете найти пример здесь

обновить

Если вышеописанное не является приемлемым решением в вашем случае, вы можете использовать событие активации, чтобы получить ссылку на созданный компонент внутри выхода маршрутизатора.

Из документов

Выход маршрутизатора будет генерировать событие активации каждый раз, когда создается экземпляр нового компонента, и событие деактивации, когда он уничтожается.

Следовательно, вы можете использовать эту функцию и выполнять свою работу. Вы можете увидеть подробный ответ здесь и в том же ответе прикреплен плункер

person Vikhyath Maiya    schedule 16.08.2017
comment
Этот ответ не имеет ничего общего с проблемой! Когда я говорю «ребенок», я имею в виду компонент в router-outlet! Пожалуйста, посмотрите на код, упомянутый в моем вопросе - person ncohen; 16.08.2017
comment
вы хотите получить доступ к myFunction внутри AppComponent правильно, или я что-то упустил? - person Vikhyath Maiya; 16.08.2017
comment
Точно... и насколько я знаю, @ViewChild используется для доступа к элементам DOM компонента! - person ncohen; 16.08.2017
comment
ViewChild используется для доступа к дочернему компоненту. Это включает в себя его шаблон И его методы. - person LarsMonty; 16.08.2017
comment
@LarsMonty Что, если я не знаю, что это за компонент? Должен ли я импортировать все возможные компоненты и получить имя с ActivatedRoute? Это выглядит не очень аккуратно... - person ncohen; 16.08.2017