我有一个Angular2应用程序,我在其中创建了一个Header组件,它在我的主App组件中呈现。
现在,我有一个其他Form组件,它的提交按钮应放在Header中。我怎么能这样做?
我需要在Header中的submit按钮和Form组件的submit方法之间进行通信。我知道做父母>孩子或孩子>父母沟通是微不足道的,但在这种情况下,我的Header和Form组件之间没有父子关系,也没有兄弟关系。
我的组件树如下所示:
- app-root
|-- app-header // -> this is where the submit button is
|-- app-edit-profile
|-- app-profile-form // -> this is my form
有人知道可能的实施吗?
答案 0 :(得分:22)
您可以创建一个在标题和表单组件之间共享的服务,您可以在其中定义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();
}
}
答案 1 :(得分:2)
除了使用Observable的解决方案之外,我认为对于EventEmitters说些什么很重要,因为在我看来,它更容易在这种情况下使用。
在子控制器中
导入EventEmitter和输出类型。
import { EventEmitter, Output } from "@angular/core
声明一个类型为EventEmitter
的输出属性 @Output() formSubmit$: EventEmitter<boolean>;
记得在构造函数中初始化EventEmitter,如下所示:
this.formSubmit$ = new EventEmitter();
最后,通过绑定到提交按钮的正确操作,触发EventEmitter&#34; emit&#34;在整个应用中传播事件的方法:
this.formSubmit$.emit(true);
在父控制器中
在父视图中,将formSubmit $事件绑定到控制器的操作:
<child-selector (formSubmit$)="handleFormSubmit($event)"></child-selector>
然后在Controller中声明方法
public handleFormSubmit(submit: boolean): void {
alert("Form has been submitted! Do your stuff here!");
}
显然,当您需要将数据从子节点交换到父控制器时,可以使用 这种策略。
答案 2 :(得分:2)
家长和孩子通过服务沟通
答案 3 :(得分:1)
使用服务和主题是最简单的方法。如果您想保留数据记录,甚至可以使用重播主题
private notify: ReplaySubject<any> = new ReplaySubject<any>();
但是,您甚至可以尝试一个名为eventbus的库。我遇到了同样的问题,而eventbus就是这个问题的正确答案。