美文网首页程序员
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