Angular:观察者 next 后的回调函数

3

我需要在Observable.next()被处理后执行一个回调函数。

我有一个组件"A",它具有使用Subject.next()发送通知的主题。 我有一个组件"B",订阅了Subject.asObservable()以执行代码。

当A触发B的下一个动作时,我希望在Subject.next()执行后执行一些代码。

服务

 private submitSubject = new Subject<String>();
 private submitObservable = this.submitSubject.asObservable();

组件 A

 public onClickSubmit():void {
      ....
      this.xxxxService.executeSubmit()
  }

组件B

ngOnInit() {
        // Subscribe to parent Submit button
        this.subscription = this.xxxService.getSubmitObservable().subscribe(value => {...} );
  }

我希望能够做类似以下的事情:

obervable.next().subscribe(e => {})

你可以通过以下方式在 submitSubject 上添加多个订阅者:this.xxxService.submitSubject.subscribe(value => {console.log(val)} ); 一旦调用 observable.next(),订阅回调函数将被执行。 - Yasser Mas
也许我理解错了问题,但是在订阅之前您可以将任何操作符pipe()到Observable中,所以您想要执行的任何操作都可以在订阅之前完成。这不是最简单的方法吗? - thomi
你能找到你问题的答案吗?因为下面的所有答案都与问题无关。我不确定,但似乎回答者没有理解被问的内容。 :) - Sasuke Uchiha
3个回答

1
In fact,我只看到了2个解决方案: - 使用2个主题/可观察对象:1用于执行,1用于结果 - 使用1个主题/可观察对象:使用subject.next进行通知和subject.complete实现,但在这种情况下,您必须为每个执行重新实例化主题/可观察对象。 1)解决方案1 组件A(父级)订阅resultNextSubject(在“next”方法上)
组件B(子级)订阅nextSubject(在“next”方法上)
在组件A中,当您单击“下一个”按钮时,它调用nextSubject.next来通知组件B进行提交(验证保存)
组件B执行提交并调用resultNextSubject.next()以通知组件A的结果 组件A接收resultNext通知并路由到另一个组件以显示 等等...
组件A(父级)
@Component({
  selector: 'pi-xxx',
  providers: [xxxService],
  templateUrl: './xxx.component.html',
  styleUrls: ['./xxx.component.scss']
})
export class xxxAComponent implements OnInit, OnDestroy {

  constructor(private router: Router, private xxxService: XxxService) {}

  ngOnInit() {  
    ...    
      // Subscribe to child notification to navigate to a tab
      this.subscription = this.xxxService.getNextResultObservable().subscribe((value) => {
    ..routing..);
     }
  }

  ngOnDestroy(): void {
      this.subscription.unsubscribe();
  }

  public onClickNext(): void {
      ...
      this.xxxService.executeNext();
  }

}

组件B(子组件)
@Component({
  selector: 'pi-tab2',
  templateUrl: './tab2.component.html',
  styleUrls: ['./tab2.component.scss']
})
export class Tab2Component implements OnInit, OnDestroy {

    private subscription:Subscription;

    constructor(private xxxService:XxxService) { }

    ngOnInit() {
        // Subscribe to parent Next button
        this.subscription = this.xxxService.getNextObservable().subscribe(value => {
            this.submit();
        });
    }

    ngOnDestroy(): void {
        this.subscription.unsubscribe();
    }

    submit() {
      ...
      // Notify result to parent
      this.xxxService.getNextResultSubject().next();
    }

}

2) 解决方案2

组件A(父级)订阅nextSubject(在'complete'方法中)

组件B(子级)订阅nextSubject(在'next'方法中)

在组件A中,当您单击“下一个”按钮时,它调用nextSubject.next通知组件B进行提交(验证保存)

组件B执行提交并调用nextSubject.complete()通知结果给组件A

组件A接收到resultNext(完成)通知并路由到另一个组件以进行显示。但是,在路由之前,组件A必须重新实例化主题及其可观察对象。


组件A

ngOnInit() {
  .... init
}

public onClickNext(): void {
      ....
          // Subscribe to wait for child result notification
          this.xxxService.nextObservable().subscribe({
              complete: () => {
                  // Must reset subject & observable before routing next child
                  this.xxxService.nextSubject =  new Subject();
                  this.xxxService.nextObservable = this.xxxService.nextSubject.AsObservable()
                  ....routing...
              }}
           );

          // Notify child
          this.xxxService.executeNext();
      }
  }

组件 B
ngOnInit() {
            // Subscribe to parent Next button
            this.subscription = this.xxxService.getNextObservable().subscribe(value => {
                this.submit();
            });
        }

        ngOnDestroy(): void {
            this.subscription.unsubscribe();
        }

        submit() {
          ...
          // Notify result (complete) to parent
          this.xxxService.getNextSubject().complete();
        }

对于如此简单的问题来说,这个解决方案太过复杂了。但是我目前还没有找到其他的解决方案。所以,谢谢你。 - Sasuke Uchiha

0
所以你已经接近成功了,你只需要订阅submitObservable(所以你需要将它设为public),当你在submitSubject上调用next时,它就会更新。下面是一个快速的例子:

服务

 private submitSubject = new Subject<any>();
 public submitObservable = this.submitSubject.asObservable();

 executeSubmit(value) {
   this.submitSubject.next(value);
 }

组件 A

onClickSubmit() {
  this.service.executeSubmit();
}

组件 B

this.subscription = this.service.submitObservable
   .subscribe(result => {
     // do something
   });

0

您可以从服务中直接返回一个Observable对象,这样executeSubmit就可以被订阅了。

 this.xxxxService.executeSubmit=()=>{
       submitSubject.next(...)
       return this.submitSubject.asObservable()
 }

在你的组件中,你可以做如下操作

 onClickSubmit() {
     return this.service.executeSubmit();
 }

执行

 onClickSubmit().subscribe()

另外,您可以使用传统的回调函数。

 onClickSubmit(cb) {
     this.service.executeSubmit();
     if(typeof cb==='function')
        cb()
 }

1
我不确定它在我的情况下是否有效,因为函数cb()将在任何时候执行,并且在组件B的Obersable.next之前执行提交操作(检查+ REST调用以存储数据)。 - Anthony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接