目录:
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:
1
2. [saveFormObs]="saveButtonEventEmitter"
3. 这种类似 [saveButton]="false"等于给变量赋值.
4. private saveButtonEventEmitter: EventEmitter<any> = new EventEmitter<any>();
5. saveButtonEventEmitter 是一个 Observable类.saveButtonEventEmitter.emit 产生Observable事件
6. this.saveFormObs
7. .takeUntil(**this**.onDestroy$)
8. .subscribe(() => {//subscribe listen 这个Observable事件
9. this.saveForm(true);
10. });
scenario2:
1. @Output() changed = **new** EventEmitter<string>();
2. click() {
3. //trigger Observable event.
4. this.changed.emit('hi~');
5. }
6. @Component({
7. //(changed)类似(onBlur),作为一种event. event 调用绑定的subscribe函数.
8. template: `<comp (changed)="subscribe($event)"></comp>`
9. })
10. export class HomeComponent {
11. subscribe(message: string) {
12. // 接收:hi~
13. }
14. }
类似项目原理一样
1. @Output() onFormInitialized: EventEmitter<boolean> = new EventEmitter<boolean>();
2. //trigger Observable event.
3. **this**.onFormInitialized.emit(**true**);
4. //event 绑定处理函数
5. (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.
下面是动态显示网页status code(pending,inprogress,registered)
1) 切换页面的时候,this.adminIdValue$.value为空,即第一次监听,所以后台把存的value发过来
2 ) BehaviorSubject has value !不仅仅是observer 3 ) value 有变化保存到后台,所以监听到new value. BehaviorSubject.next 可以给自己设value,因为next向所有监听的地方发送value,而BehaviorSubject自己监听自己,所以next发送的value,赋予了自己的value。
adminIdValue$: BehaviorSubject<string>;//template is string
this.cfgSvc.getConfigObservable(this.adminIdKEY)
.distinctUntilChanged()
.takeUntil(this.destroyMe$)
.subscribe((entry: ConfigNotification) => {
this.adminIdValue$.next(entry.object.value);
this.adminIdTextField.reset(this.adminIdValue$.value);
});
基本套路:
BehaviorSubject<String> behaviorSubject =
BehaviorSubject.create("default");
behaviorSubject.onNext("behaviorSubject3");//send
behaviorSubject.subscribe(new Observer<String>() {//receive
...
}
BehaviorSubject 和Subject的区别?
Subject是基类,具体使用的是4个子类,BehaviorSubject是其中常见的一个.
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等)的处理.
1. FileUpload = __decorate([
2. core_1.Component({
3. selector: 'fileUpload',
4.
template: "\n [ngStyle]=\"style\" [class]=\"styleClass\" *ngIf=\"mode === 'advanced'\ (drop)=\"onDrop($event)\"...">\n
5. .....
6. }),
7. ], FileUpload);
9. FileUpload.prototype.onDrop = **function** (event) {
10. **this**.onFileSelect(event);
11. };
13. FileUpload.prototype.onFileSelect = **function** (event) {
14. **this**.upload();
15. }
16. FileUpload.prototype.upload = **function** () {
17. //发送emit到cer.html
18. **this**.uploadHandler.emit({
19. files: **this**.files
20. });
21. }
23. cer.html:
24. <p-fileUpload #installCertFileUpload
25. //uploadHandler 等着emit,收到emit,对应的函数onInstallCertFileSelected就执行.
26. (uploadHandler)="onInstallCertFileSelected($event)"
27. </p-fileUpload>
29. cer.ts:
30. private onInstallCertFileSelected(event): void {
31. //具体实现功能
32. //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', er|ror); 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
});
网友评论