角度6可观察到

时间:2018-08-12 21:57:48

标签: angular rxjs subject unsubscribe switchmap

我有一种情况,我想无限期地暂停可观察的事件并在事件发生时恢复它。

让我尝试在这里解释我要实现的目标。

我有组件blockIncarnateblockControl。 BlockIncarnate是基于数组添加到DOM中的,而blockControl是在事件上动态添加的。

现在,我需要在BlockIncarnates和BlockControl之间进行通信。我正在使用带有“主题”的服务以使通信成为可能。我在这里面临的问题是只有一个blockIncarnate应该监听blockControl。添加新的blockIncarnate时,blockControl应该切换到新的blockIncarnate。如果用户单击特定的blockIncarnate blockControl,则会切换为单击的那个。

到目前为止,我已经尝试过

  • 取消订阅并再次订阅,但好像我无法订阅 再次取消订阅主题。
  • SwitchMap,似乎不起作用。 switchMap( (update: {field:string, value:string} => update))引发错误。 Argument of type '(updated: { field: string; value: string; }) => { field: string; value: string; }' is not assignable to parameter of type '(value: { field: string; value: string; }, index: number)。此外,当我switchMap( (update: {field:string, value:string} => update.value))将字符串分解为字符并订阅时,它会逐字符接收。

下面我粘贴一些代码 广播服务

export class BroadcasterService {

    subscriptionTracker: Subscription;

    blockControls = new Subject<{field: string, blockIndex: number}>();
    blockUpdates = new Subject<{field: string, value: string}>();

    emitBlockControl(data) {
        this.blockControls.next(data);
    }

    listenBlockControl(): Observable<{field: string, blockIndex: number}> {
        return this.blockControls.asObservable();
    }

    emitBlockUpdate(data) {
        this.blockUpdates.next(data);
    }

    listenBlockUpdate(): Observable<{field: string, value: string}> {
        return this.blockUpdates.asObservable();
    }

    trackSubscription(subscription: Subscription){
        console.log('add subscription to tracker', this.subscriptionTracker)
        if(this.subscriptionTracker === undefined){
            this.subscriptionTracker = subscription;
        }
        else{
            this.subscriptionTracker.add(subscription);
        }
    }

    destroyPreviousChannels(){
        console.log('clean tracker', this.subscriptionTracker);
        if(this.subscriptionTracker){
            // this.subscriptionTracker.forEach(s => s.unsubscribe());

            this.subscriptionTracker.unsubscribe();
        }

        // return of(true);
    }


}

封闭性元素

ngOnInit() {
    if(this.block){
        console.log('Initiate new block incarnate', this.block)
        // this.superviseChannelsService.establishBlockUpdatesChannel(this.block);

        // Receive block updates from controls
        this.blockIncarnateSubscription = this.broadcasterService.listenBlockUpdate()
        .subscribe((update: {field: string, value: string}) => {
            console.log('Updating block incarnates data', this.block)
            this.block[update.field] = update.value;
        })
    }
}

块控制组件

export class BlockControlComponent implements OnInit, ControlComponentMold, OnDestroy {
    @Input() dataObject: BlockModel; //shall receive a block

    paramStyle = '';
    paramCssClass = '';

    constructor(private broadcasterService: BroadcasterService) { }

    ngOnInit() {
        console.log('Init block control component', this.dataObject)
    }

    emitControl(controlType){
        this.broadcasterService.emitBlockControl({
            field: controlType, blockIndex:this.dataObject.placing});
    }

    emitUpdate(field){
        let value = (field === 'style') ? this.paramStyle : this.paramCssClass;
        this.broadcasterService.emitBlockUpdate({field: field, value: value});
    }

    ngOnDestroy(){
        console.log('destroying block control compoennet')
        // this.broadcasterService.destroyPreviousChannels();
    }

}

这是我正在玩的一些代码

export class SuperviseChannelsService {

    private blockIncarnateSubscription: Subscription;



    constructor(private broadcasterService: BroadcasterService) { }

    /* Params:
     *      block BlockModel
     * Through this method we will subscribe/listen to blockUpdates Subject
     * broadcasted by broadcaster. Although we are listening to every update,
     * method will only modify BlockModel provided at the time of establishing
     * channel.
     */
    establishBlockUpdatesChannel(block: BlockModel){
            this.broadcasterService.listenBlockUpdate()
            .pipe(
                // map( (res: Column) => res ),
                switchMap( (updated: Column) => {
                    console.log('sldsfjfn', updated)
                    return updated.value;
                } ),
                // concatMap( val => {
                //     console.log('concate string', val)
                //     return val
                // })
            )
            .subscribe((value:string) => {
                console.log(value)
                block['style'] = value;
                // block[update.field] = update.value;
            })
    }

}

我来自AngularJS,所以我不太了解Angular / rxjs。有解决这个问题的更好方法吗?

0 个答案:

没有答案