Angular2 метод вызова другого компонента
У меня есть приложение Angular2, в котором я создал компонент заголовка, который отображается в моем основном компоненте приложения.
Теперь у меня есть другой компонент Form, который должен иметь свою кнопку отправки, помещенную в заголовок. Как я могу это сделать?
Мне нужно общаться между кнопкой отправки в заголовке и методом отправки компонента Form. Я знаю, что тривиально выполнять родительское > дочернее или дочернее > родительское общение, но в этом случае между моими компонентами Header и Form нет отношений между родителями и дочерними элементами, а также отношения между сестрами.
Мое дерево компонентов выглядит следующим образом:
- app-root
|-- app-header // -> this is where the submit button is
|-- app-edit-profile
|-- app-profile-form // -> this is my form
Есть ли у кого-нибудь представление о возможной реализации?
Ответы
Ответ 1
Вы можете создать одну услугу, которая будет использоваться между вашим заголовком и компонентом формы, в котором вы можете определить Observable
, чтобы вы могли подписаться на эту форму Observable
из формы и выполнить некоторые действия, когда вы получите некоторое значение из заголовка.
common.service.ts
import { Injectable, Inject } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class CommonService {
private notify = new Subject<any>();
/**
* Observable string streams
*/
notifyObservable$ = this.notify.asObservable();
constructor(){}
public notifyOther(data: any) {
if (data) {
this.notify.next(data);
}
}
}
header.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { CommonService } from './common.service';
@Component({
selector : 'header',
templateUrl : './header.html'
})
export class HeaderComponent implements OnInit, OnDestroy {
constructor( private commonService: CommonService ){
}
ngOnInit() {
}
onSubmit(){
// this method needs to be called when user click on submit button from header
this.commonService.notifyOther({option: 'onSubmit', value: 'From header'});
}
}
form.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { CommonService } from './common.service';
@Component({
selector : 'form',
templateUrl : './form.html'
})
export class FormComponent implements OnInit, OnDestroy {
private subscription: Subscription;
constructor( private commonService: CommonService ){
}
ngOnInit() {
this.subscription = this.commonService.notifyObservable$.subscribe((res) => {
if (res.hasOwnProperty('option') && res.option === 'onSubmit') {
console.log(res.value);
// perform your other action from here
}
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
Ответ 2
Помимо решения с Observable, я думаю, что важно сказать что-то о EventEmitters, как они, на мой взгляд, проще в использовании в таких сценариях.
В дочернем контроллере
импортировать типы EventEmitter и Output.
import { EventEmitter, Output } from "@angular/core
объявить свойство вывода типа EventEmitter
@Output() formSubmit$: EventEmitter<boolean>;
не забудьте инициализировать EventEmitter в конструкторе следующим образом:
this.formSubmit$ = new EventEmitter();
и, наконец, с надлежащим действием, связанным с кнопкой отправки, вызвать метод "emit" EventEmitter для распространения события через ваше приложение:
this.formSubmit$.emit(true);
В родительском контроллере
В родительском представлении привяжите событие formSubmit $к действию контроллера:
<child-selector (formSubmit$)="handleFormSubmit($event)"></child-selector>
затем объявите метод в контроллере
public handleFormSubmit(submit: boolean): void {
alert("Form has been submitted! Do your stuff here!");
}
Очевидно, что эту стратегию можно использовать только, когда вам нужно обмениваться данными с дочерним элементом на родительский контроллер.
Ответ 3
Родитель и дети общаются через службу
Angular2 метод вызова другого компонента
Ответ 4
Использование услуг и предметов - самый простой способ. Если вы хотите сохранить запись своих данных, вы можете даже использовать тему воспроизведения
private notify: ReplaySubject<any> = new ReplaySubject<any>();
Но вы можете даже попробовать библиотеку, называемую eventbus. Я столкнулся с теми же проблемами, и eventbus - это правильный ответ для этого.