angular - 如何使用BehaviorSubject封装加载器服务逻辑

标签 angular rxjs

我有 Angular 大学类(class)的加载程序服务:


@Injectable()
export class LoadingService {
  private loadingSubject = new BehaviorSubject<boolean>(false);
  loading$: Observable<boolean> = this.loadingSubject.asObservable();

  showLoaderUntilCompleted<T>(obs$: Observable<T>): Observable<T> {
    return of(null).pipe(
      tap(() => this.on()),
      concatMap(() => obs$),
      finalize(() => this.off())
    );
  }

  on() {
    this.loadingSubject.next(true);
  }

  off() {
    this.loadingSubject.next(false);
  }
}

它在组件中的用法:

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  providers: [LoadingService]
})
export class AppComponent {
  loading$: Observable<boolean>;
  constructor(private loader: LoadingService) {
    this.loading$ = loader.loading$;
  }
  submit() {
    this.loader.showLoaderUntilCompleted(timer(1000)).subscribe();
  }

  submit2() {
    this.loader.showLoaderUntilCompleted(timer(1000)).subscribe();
  }
}

模板:

<form (ngSubmit)="submit()">
  {{ loading$ | async }}
  <button type="submit">Submit</button>
</form>

<form (ngSubmit)="submit2()">
  {{ loading$ | async }}
  <button type="submit">Submit</button>
</form>

在组件只有一种表单的情况下它可以完美地工作,有人可以建议我如何在页面上的多个表单中重用它吗? 目标是为每个表单提供不同的加载器状态。

链接到stackblitz

最佳答案

你自己回答了这个问题。 “目标是为每个表单提供不同的加载器状态” - 因此每个表单都需要它自己的加载器。

您可以为两个独立的不相关加载程序创建两个不同的服务实例。

Controller

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
  providers: [LoadingService]
})
export class AppComponent {
  private loader1: LoadingService;
  private loader2: LoadingService;

  loading1$: Observable<boolean>;
  loading2$: Observable<boolean>;

  constructor() {
    this.loader1 = new LoadingService();
    this.loader2 = new LoadingService();

    this.loading1$ = this.loader1.loading$;
    this.loading2$ = this.loader2.loading$;
  }

  submit() {
    this.loader1.showLoaderUntilCompleted(timer(1000)).subscribe();
  }

  submit2() {
    this.loader2.showLoaderUntilCompleted(timer(1000)).subscribe();
  }
}

模板

<form (ngSubmit)="submit()">
    {{ loading1$ | async }}
    <button type="submit">Submit</button>
</form>

<form (ngSubmit)="submit2()">
    {{ loading2$ | async }}
    <button type="submit">Submit</button>
</form>

我修改了你的Stackblitz .

关于angular - 如何使用BehaviorSubject封装加载器服务逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66495461/

相关文章:

angular - Angular 在哪里存储全局数据?

javascript - 如何禁用浏览器菜单栏中的刷新按钮

angular - 我已经遵循了可信网络事件的所有步骤,但使用 chrome dev 仍然可以看到地址栏。如何在可信网络事件中获取 webview?

javascript - Angular 2 - 组件属性更改但 View 不更新

angular - 使用异步代码扫描操作符

rxjs - 使用相应的 flatMap 结果压缩值

javascript - 在 Angular 中显示动态过滤的数组

angular - 如何处理可能为空的 rxjs 可观察响应?

angular - 有没有办法在延迟运算符之后将流 "Cancel"

javascript - Angular 7 中的管道和 map 之间的确切区别是什么?