Angular 6 — Отправитель событий из подмодуля в родительский модуль

#angular

#angular

Вопрос:

У меня есть структура проекта, подобная приведенной ниже

 src
  -> app
        -> ui
             ->header
             ->layout
             ui.module.js
    app.component.css
    app.component.html
    app.component.ts
    app.module.ts
  

В папке заголовка у меня есть файлы html, css и ts. в ts-файле у меня есть переменная для отправки родительскому (app.component.ts)

Мой код отправителя ts-файла «заголовка», как показано ниже

 @Output() highlightedMenu1 = new EventEmitter<string>();


somemthod(s : string){ //this some method will be called on click event from "header" html
    this.highlightedMenu1.emit('hi'); //wanted to emit this variable to app.component.ts
}
  

Мой код отправителя HTML-файла «header», как показано ниже

 (highlightedMenu1)="getMenuBarSelected($event)"
  

«ui.module.js » экспортированы как «заголовок», так и «макет».

в app.component.ts объявлен метод, подобный приведенному ниже

ожидаю, что этот метод будет вызван. из html-кода «header», но он не вызывался, вместо этого, если у меня есть этот метод в моем модуле «layout», отправитель работает нормально.

 getMenuBarSelected(s: string) {
    console.log('string =========* ');
  }
  

«app.module.ts» я импортировал «UIModule»

Комментарии:

1. Вы пробовали точку останова, чтобы убедиться, что ваше событие, которое должно вызывать somethod(s: string) метод, действительно вызывается? Ваш отправитель событий highlightedMenu1 должен работать правильно, хотя я бы не советовал использовать цифры в каких-либо функциях или именах переменных. Если метод вызывается для отправки, попробуйте изменить highlightedMenu1 на highlightedMenuOne и посмотрите, работает ли это по-другому.

2. somemethod успешно вызван. Переименование highlightedMenu1 также выполнено, но не работает

Ответ №1:

@Output позволяет родительскому модулю подписаться на отправитель событий, объявленный в его дочернем модуле.


Если header.component.ts имеет highlightedMenu1

 @Output() highlightedMenu1 = new EventEmitter<string>();


somemthod(s : string){ //this some method will be called on click event from "header" html
    this.highlightedMenu1.emit('hi'); //wanted to emit this variable to app.component.ts
}
  

Header.component.html не может иметь следующего, потому что это часть того же компонента:

 (highlightedMenu1)="getMenuBarSelected($event)"//wrong
  

Скорее, некоторый родительский компонент может иметь следующее:

layout.component.html

 <app-header (highlightedMenu1)="getMenuBarSelected($event)"></app-header>//right
  

предполагается, что getMenuBarSelected определено внутри layout.component.ts


Редактировать:

@Output события не всплывают, как, скажем, click событие и т.д. Таким образом, у дедушки и бабушки нет способа узнать, было ли запущено событие в grandchild. Однако вы можете создать другое событие @output внутри прямого родительского модуля, чтобы бабушка и дедушка могли его прослушать.

Предполагая:

app.component (прародитель) -> layout.component (родительский) -> header.component (дочерний)

В дополнение к приведенному выше коду вам понадобится: layout.component.ts

 @Output() highlightedMenu1 = new EventEmitter<string>();
  

layout.component.html

 <app-header (highlightedMenu1)="highlightedMenu1.emit($event)"></app-header>
  

app.component.html

 <app-layout (highlightedMenu1)="myMethod($event)"></app-layout>
  


Другой более простой способ — иметь некоторые EventService .
EventService.ts

 static highlightedMenu1 = new EventEmitter<string>();
  

и в header.component.ts

    myMethod(){
       EventService.highlightedMenu1.emit('hi');
   }
  

и в app.component.ts

 EventService.highlightedMenu1.subscribe(data => console.log(data));
  


Stackblitz

Комментарии:

1. я также пробовал этот подход «<app-header (highlightedMenu1) =»getMenuBarSelected ($ event)»></app-header>», если у меня есть «getMenuBarSelected», определенный внутри «layout.component.ts», это работает, но я ожидаю, что я хочу получить доступ к переменной источника событий из header.component.ts в app.component.ts, а не из «layout.component.ts»

2. Он никогда не достигает метода app.component.ts. добавлен код типа «<app-header (highlightedMenuone)=»getMenuBarSelected($event)»></app-header>» в layout.component.hrml. И <app-layout (highlightedMenuone)=»getMenuBarSelected($event)»> в app.component.html И getMenuBarSelected(s: string) { console.log(‘строка =========* ‘ s); } в app.component.ts

3. это не выделенное меню, а выделенное меню 1. Я создал stackblitz. проверьте мою правку