美文网首页
[Rxjs] Subject的使用

[Rxjs] Subject的使用

作者: V_Jan | 来源:发表于2020-11-12 10:08 被阅读0次

    https://rxjs-dev.firebaseapp.com/guide/subject
    Subject可以实现多播。
    一个使用场景:比如在父组件里初始化一个subject, 提供一个函数作为对外获取这个subject的入口,
    子组件通过这个函数订阅这个subject, 等待父组件发号司令(往这个subject里放值)后,子组件同时做出各自的动作,比如发射值。

    以官网例子,简单解释

    import { Subject } from 'rxjs';
     
    const subject = new Subject<number>(); //初始化一个subject
     
    subject.subscribe({  //产生订阅者1
      next: (v) => console.log(`observerA: ${v}`)
    });
    subject.subscribe({//产生订阅者2
      next: (v) => console.log(`observerB: ${v}`)
    });
     
    subject.next(1); //给subject喂值的时候,上面2位订阅者就能收到这个值,并且各自打印信息
    subject.next(2);//给subject喂值的时候,上面2位订阅者就能收到这个值,并且各自打印信息
    
    subject.subscribe({//产生订阅者3,在父组件发出值之后订阅,它收不到父组件的值,BehaviorSubject可以让她收到
      next: (v) => console.log(`observerC: ${v}`)
    });
    

    BehaviorSubject可以缓存最后一个发出的值,所以只要有订阅者订阅,它会立刻收到最后一个值。如果你有这样的使用场景,那么就要在父组件里声明一个BehaviorSubject对象,而不是Subject对象。

    下面是我的使用场景和代码
    父组件里声明用于广播的subject:

    subject = new Subject<any>();
    //用于发号司令,以通知子组件emit各自的值出来, 这里的value可以做不同用途,比如这个subject我既用于做create,也用于做update, 那么我可以发射不同的值,比如create, update用于告诉子组件现在是收集什么场景下的值,因为可能不同的场景需要做额外处理。
    broadcastReadySignal(value: any) { 
            this.subject.next({message: value})
        }
     clearMessage() { // 一轮广播结束后,即使用结束后, 清除订阅。
            console.log('[DEBUG]clear RXJS subject message')
            // this.subject.next(null);
            this.subject.unsubscribe();
        }
     getMessage(): Observable<any> {//用于给子组件调用,以获得父组件的subject句柄
            return this.subject.asObservable();
        }
    //主要的触发接口,createJob的时候触发广播事件,以通知各子组件emit各自的值出来,在这里前端使用的是vue,通过vue的响应式更新可以收集到子组件emit出来的值。 
     createJob() {
            this.broadcastReadySignal('create');
            //other codes...
    }
    

    所有子组件都这么写,mounted()或者created()[这是vue的生命周期方法]里,订阅父组件的subject,一旦收到父组件的值后,就做this.$emit('update:data', this.formData)这个动作。这个动作就是弹射出子组件的Form的值以更新父组件的data, 这两个值是绑定的,是父子组件数据沟通的地方:

    mounted() {
            //this.formData = this.data;
            this.jobOperate.getMessage().subscribe((next: any) => {
                this.$emit('update:data', this.formData)
            })
        }
    

    如果你看不懂this.$emit('update:data', this.formData),那就先看看Vue的Sync修饰符:
    https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier

    相关文章

      网友评论

          本文标题:[Rxjs] Subject的使用

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