美文网首页程序员
emit,EventEmitter,subscribe,next

emit,EventEmitter,subscribe,next

作者: mfdalf | 来源:发表于2020-11-05 15:53 被阅读0次
    image
    目录:
    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
      });
    

    相关文章

      网友评论

        本文标题:emit,EventEmitter,subscribe,next

        本文链接:https://www.haomeiwen.com/subject/uwfavktx.html