emit,EventEmitter,subscribe,next,subject 使用

 

目录:

1  EventEmitter 介绍

2  subscribe 介绍

3  Subject 介绍

4   应用: Angular 组件之间通讯

5  公司项目

6 history

 

1 EventEmitter 介绍

EventEmitter 是封装的Observable类

export class Subject extends Observable
export declare class EventEmitter extends Subject 

 

EventEmitter 2种用法:一个emit 是@input,一个是@output

  1. scenario1:  
  2. [saveFormObs]="saveButtonEventEmitter"  
  3. 这种类似 [saveButton]="false"等于给变量赋值.  
  4. private saveButtonEventEmitter: EventEmitter = new EventEmitter();  
  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();  
  2. click() {  
  3.     //trigger Observable event.  
  4.     this.changed.emit('hi~');  
  5. }  
  6. @Component({  
  7.     //(changed)类似(onBlur),作为一种event. event 调用绑定的subscribe函数.  
  8.   template: `"subscribe($event)">`  
  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;

   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() {
					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;//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 behaviorSubject = BehaviorSubject.create("default");
 behaviorSubject.onNext("behaviorSubject3");//send
 behaviorSubject.subscribe(new Observer() {//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();

//调用关系

(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 = new Subject();//定义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的调用关系
 比如: (uploadHandler)="onInstallCertFileSelected($event)">

   

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);  
  8.       
  9.     FileUpload.prototype.onDrop = function (event) {  
  10.                 this.onFileSelect(event);  
  11.     };  
  12.       
  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.      }  
  22.        
  23. cer.html:  
  24.  
  25.  //uploadHandler 等着emit,收到emit,对应的函数onInstallCertFileSelected就执行.  
  26.      (uploadHandler)="onInstallCertFileSelected($event)"  
  27.           
  28.        
  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', error);
                        this._msgSvc.setMessage(this.STR_INSTALLCSRERROR_MSG, this.ERROR_MESSAGE_TYPE);
                    },
                    complete: () => {
    //stop progressbar for uploading
                        this.uploadInProgress = false;
                    }
                });
  33. }  

如果将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
  });

你可能感兴趣的:(angularjs)