目录:
1 EventEmitter 介绍
2 subscribe 介绍
3 Subject 介绍
4 应用: Angular 组件之间通讯
5 公司项目
6 history
1 EventEmitter 介绍
EventEmitter 是封装的Observable类
export class Subject<T> extends Observable<T>
export declare class EventEmitter<T> extends Subject<T>
EventEmitter 2种用法:一个emit 是@input,一个是@output
- scenario1:
- [saveFormObs]="saveButtonEventEmitter"
- 这种类似 [saveButton]="false"等于给变量赋值.
- private saveButtonEventEmitter: EventEmitter<any> = new EventEmitter<any>();
- saveButtonEventEmitter 是一个 Observable类.saveButtonEventEmitter.emit 产生Observable事件
- this.saveFormObs
- .takeUntil(this.onDestroy$)
- .subscribe(() => {//subscribe listen 这个Observable事件
- this.saveForm(true);
- });
scenario2:
- @Output() changed = new EventEmitter<string>();
- click() {
- //trigger Observable event.
- this.changed.emit('hi~');
- }
- @Component({
- //(changed)类似(onBlur),作为一种event. event 调用绑定的subscribe函数.
- template: `<comp (changed)="subscribe($event)"></comp>`
- })
- export class HomeComponent {
- subscribe(message: string) {
- // 接收:hi~
- }
- }
类似公司项目原理一样
- @Output() onFormInitialized: EventEmitter<boolean> = new EventEmitter<boolean>();
- //trigger Observable event.
- this.onFormInitialized.emit(true);
- //event 绑定处理函数
- (onFormInitialized)="handleFormInitialized($event)"
2: subscribe介绍:
subscribe 表示监听
2.1 那么什么会trigger这个listen呢,
1)Observable 变量(Observable.emit trigger)
@Input() saveFormObs: Observable<any>;
this.saveFormObs //
.takeUntil(this.onDestroy$)
.subscribe(()
2)有控件变化
this.authPwCtrl.valueChanges
.takeUntil(this.destroyMe$)
.debounceTime(100)
.subscribe((value) =>
2.2: subscribe 是订阅,有变化就发送后台。next是接收后台的返回数据.,
基本套路,emit(or click etc event)--subscribe--next(onCompleted,onError,onNext.处理返回值)
conferenceSubscription = confSvc.getConferenceObservables()
.getConnectionObservable()
.getObservable()
.subscribe(new Observer<Connection>() {
private ConnectionState currentState;
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Connection connection) {
//The onNext() will be invoked many times with same connection state
//Only need to print when the state changed
if(connection.getState() != currentState){
currentState = connection.getState();
onChange(connection, connection.getState());
}
}
});
3: subject 介绍
subject 这个东西,挺厉害既可以当成observable 又可以当成observer.
用法: var subject = new Rx.Subject();
//subject等于getConnectionObservable,相当于observablevar subscription = subject.subscribe(
x => console.log('onNext: ' + x),
e => console.log('onError: ' + e.message),
() => console.log('onCompleted'));
}
//subject 等于
getConnectionObservable.subscribe 相当于observer
subject.onNext(1);
// => onNext: 1
subject.onNext(2);
// => onNext: 2
subject.onCompleted();
// => onCompleted
this.saveRequest$.next ({
control: this.control as PFormControl,
options: options
} as ControlSaveRequest);
this.saveRequest$.next 和this.saveRequest$.onNext是一样的
4 应用: Angular 组件之间通讯
http://www.cnblogs.com/zheng-chuang/p/7418295.html
https://zhouhao.me/2017/09/17/communication-between-component/
上面两篇文章划重点,
1) 父子组件通讯
在同一个文件or import ChildComponent(Child.ts)
只用emit,@Output,连subscribe都没用
@Output() //发起是Output
public follow=new EventEmitter<string>();
//调用关系
(click)="emitAnEvent()"//父组件触发---this.follow.emit("follow emit");//emit----(follow)="doSomething()" //child(follow)接收,doSomething处理业务note: 可以通过入参传递内容
2) 没有父子关系的组件通讯
child-1,child-2 都用公共的service,一个向service push message,另一个subscribe service message.
@Injectable()//因为child-1.ts 要使用另一个ts文件,event-bus.service.ts的变量,所以要Inject
public eventBus:Subject<string> = new Subject<string>();//定义Subject for observable and observer
//调用关系
(click)="triggerEventBus()"//child-1组件触发---this.eventBusService.eventBus.next//在Subject的情况下这个next表示emit---this.eventBusService.eventBus.subscribe((value)//child-2监听subscribe service获取push的message
notes:OnDestory 要unsubscribe,否则会内存泄漏
3) 例子缺点,对@Input使用没有说明
5 公司项目
这里例子和公司自定义封装html成标签fileUpload是一样的。
button drop事件trigger "uploadHandler emit",然后uploadHandler绑定onInstallCertFileSelected.
实现了回调函数从fileupload.js 调到certificate-table.html在到certificate-table.ts的调用关系
比如:<fileUpload
(uploadHandler)="onInstallCertFileSelected($event)">
</fileUpload>
fileupload.js
自定义的fileUpload,就是一段html封装成了标签.fileUpload实际就是一个button控件以及button各种事件(比如drop等)的处理.
- FileUpload = __decorate([
- core_1.Component({
- selector: 'fileUpload',
- template: "\n [ngStyle]=\"style\" [class]=\"styleClass\" *ngIf=\"mode === 'advanced'\ (drop)=\"onDrop($event)\"...">\n
- .....
- }),
- ], FileUpload);
- FileUpload.prototype.onDrop = function (event) {
- this.onFileSelect(event);
- };
- FileUpload.prototype.onFileSelect = function (event) {
- this.upload();
- }
- FileUpload.prototype.upload = function () {
- //发送emit到cer.html
- this.uploadHandler.emit({
- files: this.files
- });
- }
- cer.html:
- <p-fileUpload #installCertFileUpload
- //uploadHandler 等着emit,收到emit,对应的函数onInstallCertFileSelected就执行.
- (uploadHandler)="onInstallCertFileSelected($event)"
- </p-fileUpload>
- cer.ts:
- private onInstallCertFileSelected(event): void {
- //具体实现功能
- //it is a httpput to upload file
this._certService.installCertificate(formData).subscribe({
next: (response) => {
this.fetchInstalledCertificates(); // On a successful install, fetch the updated list of installed certificates.
this._msgSvc.setMessage(this.STR_INSTALLCSRSUCCESS_MSG, this.SUCCESS_MESSAGE_TYPE);
// Refresh the browser in event the server certificate was changed
window.setTimeout(() => window.location.reload(false), this.BROWSER_RELOAD_DELAY_MS);
}, error: (error) => {
this._logger.error('[CertificatesPage] Install certificates returned error', error);
this._msgSvc.setMessage(this.STR_INSTALLCSRERROR_MSG, this.ERROR_MESSAGE_TYPE);
},
complete: () => {
//stop progressbar for uploading
this.uploadInProgress = false;
}
}); - }
如果将FileUpload中的button写到cer.html中也可以实现。为什么要这么做呢?
这样做,可以实现控件和具体业务分离,实现复用。
这样每个网页,都可以调用p-fileUpload,实现button以及upload进度条,每个网页加上自己的change 函数内容即可
6 other: history
html--ajax--promise---observable 技术进化过程
这里主要以angularjs过渡到angular中使用RxJS为例。next应该是observer的.
普通的Promise:
对于一个普通的promise,我们一般处理如下:
promise().then(
()=>{
// success
},
()=>{
// error
});
而在RxJS中,我们一般得到的是一个Observable(可观察对象),
类似的像上面一样的处理被称为订阅,其实现如下:
observable().subscribe(
()=>{
// next
},
()=>{
// error
},
()=>{
// complete
});