【问题标题】:Re-trigger service call to repeat an asynchronous request重新触发服务调用以重复异步请求
【发布时间】:2020-01-22 15:09:22
【问题描述】:

想象一下 Angular 组件中显示的用户列表。我注入我的服务并在我的模板中订阅它。

我还有一个对话框,您可以在其中将用户添加到我的表中。添加并关闭对话框后,我想通过重新触发服务调用来刷新表格。

组件:

export class UserComponent implements OnInit {
  public users$!: Observable<User[]>;

  constructor(
    public dialog: MatDialog,
    private userService: UserService,
  ) {}

  public ngOnInit() {
    this.users$ = this.userService
      .getAllUsers$()
      .pipe(take(1));
  }

  public openAddUserDialog() {
    this.dialog
      .open(AddUserDialogComponent)
      .afterClosed()
      .subscribe(() => {
        // TODO re-trigger observable here?
      });
  }
}

模板:

<p *ngFor="user of users$ | async">{{ user.name }}</p>

如何从对话框中重新触发afterClosed() 函数中的服务调用? 我不想在我的订阅中订阅这个。

我相信一定有一种模式可以将 getAllUsers$() 的返回值与另一个 Observable 连接起来,并在那里推送一些东西,然后重新触发该过程。

【问题讨论】:

  • 这个问题的答案对你来说足够好了吗? stackoverflow.com/a/59846491/9880876 他们使用主题来重新触发对 API 的调用
  • 我正要分享一样哈哈(我是作者)。弗洛里安,上面的链接绝对是要走的路(与你当前的架构)。如果您有一家商店(例如使用 ngrx),可能会更容易处理,但这是另一个话题 :)
  • 谢谢,发布这个答案对我有很大帮助。但我选择了reapeatWhen() 方法,因为我认为它更直观和可读。也感觉算子就是为这种场景而生的。

标签: angular typescript rxjs angular-material


【解决方案1】:

我最终使用了reapeatWhen() 运算符,因为它是我认为最直观和最具描述性的方式。

调整我的答案,以便仅在真正添加用户时重新获取用户列表

export class UserComponent implements OnInit {
  public users$!: Observable<User[]>;

  private refetchUsers$ = Subject();

  constructor(
    public dialog: MatDialog,
    private userService: UserService,
  ) {}

  public ngOnInit() {
    this.users$ = this.userService
      .getAllUsers$()
      .pipe(
        take(1),
        repeatWhen(() => refetchUsers$),
      );
  }

  public openAddUserDialog() {
    this.dialog
      .open(AddUserDialogComponent)
      .afterClosed()
      .pipe(filter((userAdded) => userAdded))
      .subscribe(() => {
        this.refetchUsers$.next();
      });
  }
}

【讨论】:

    【解决方案2】:

    不知道这是否是最佳做法,但你可以试试这个:

    export class UserComponent implements OnInit {
      public users$!: Observable<User[]>;
    
      constructor(
        dialog: MatDialog,
        private userService: UserService,
      ) {}
    
      ngOnInit() {
        this.getUsers();
      }
    
      openAddUserDialog() {
        this.dialog
          .open(AddUserDialogComponent)
          .afterClosed()
            .pipe(
              filter(user => !!user), // Avoid closing modal without creating a new user
              tap(() => this.getUsers()))
          .subscribe();
      }
    
      getUsers() {
        this.users$ = this.userService
          .getAllUsers$()
          .pipe(take(1));
      }
    }
    

    【讨论】:

    • 我不明白你的方法。每次关闭 users$ 类变量时,您都会使用冷的 Observable 设置它。你试过了吗?我不相信这行得通。
    • @FlorianLeitgeb 我没有使用 Dialog 在 Stackblitz 上实现这一点,但我尝试重现它并且它正在工作。 See here
    • 我们同意主题更好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多