Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular RxJS:使用merge动态添加和删除Observable_Angular_Typescript_Rxjs_Rxjs6 - Fatal编程技术网

Angular RxJS:使用merge动态添加和删除Observable

Angular RxJS:使用merge动态添加和删除Observable,angular,typescript,rxjs,rxjs6,Angular,Typescript,Rxjs,Rxjs6,我正在尝试构建一个可插拔的ProgressService 服务应该跟踪当前加载的“东西”数量。并且有一个isLoading()方法,该方法返回一个可观察的,以指示是否有任何东西正在加载 我的第一个解决方案非常简单,使用了一个新的行为子对象(0),然后每个加载提供程序只调用ProgressService.increase()和ProgressService.decrease()。这很有效。但如果可能的话,现在我想做更多的反应 然后我遇到了merge,当所有加载提供程序在开始时都是已知的时,它可以

我正在尝试构建一个可插拔的
ProgressService

服务应该跟踪当前加载的“东西”数量。并且有一个
isLoading()
方法,该方法返回一个
可观察的
,以指示是否有任何东西正在加载

我的第一个解决方案非常简单,使用了一个
新的行为子对象(0)
,然后每个加载提供程序只调用
ProgressService.increase()
ProgressService.decrease()
。这很有效。但如果可能的话,现在我想做更多的反应


然后我遇到了
merge
,当所有加载提供程序在开始时都是已知的时,它可以正常工作:

this.progress=merge(…progressProviders).pipe(
扫描((acc,curr)=>acc+(curr?1:-1),0)
);
当任何加载提供程序发出
true
false
时,这只会增加/减少
progress

但我还需要某种注册/注销功能。这基本上应该在
合并链中添加一个新的
可观察链
(或将其删除)


新的
ProgressService
应如下所示:

类进程服务{
进度:Observable=EMPTY;//加载时值>0
addLoadingProvider(lp:可观察){
//当lp发出true时,增加this.progress
//当lp发出false时,减少此值。进度
//很好:如果lp的第一个发出值为false,则忽略
}
removeLoadingProvider(lp:可见){
//停止听lp
//清理:如果lp上次发出为真,则减少此进度
}
isLoading():可观察{
返回此.progress.pipe(
映射(val=>val!==0)
);
}
}
如果我们从
addLoadingProvider
返回
Subscription
,并使用
Subscription.unsubscripte()
取消注册,则可能根本不需要
removeLoadingProvider
方法(?)


希望有人能告诉我如何根据需要合并和取消合并其他观测值。

根据您的解释,我可以理解以下内容[如果我的理解不正确,请纠正我]-

您希望收集发出布尔值的各种观察值,并希望以这种方式跟踪,如果其中任何一个至少有一个
“true”
,则您的最终观察值应发出true,否则最终观察值应返回
“false”

尽管你的行为主体方法是一种被动的方法。我建议采取以下办法:;让我知道这在你的场景中是否有意义-

方法1-

enum ListAction {
  Added,
  Removed,
  Empty,
  Undefined
}

export class ProgressService {

  constructor() { }

  progress: Observable<number> = EMPTY; // value > 0 when something is loading

  obsListChanged: BehaviorSubject<ListAction> = new BehaviorSubject<any>(ListAction.Undefined);
  obsList: Array<Observable<boolean>> = [];

  addLoadingProvider(lp: Observable<boolean>) {
    // increment this.progress, when lp emits true
    // decrease this.progress, when lp emits false
    // nice to have: ignore if lp's first emitted value is false
    this.obsList.push(lp);

    this.obsListChanged.next(ListAction.Added);
  }

  removeLoadingProvider(lp: Observable<boolean>) {
    // stop listening to lp
    // clean up: decrease this.progress, if lp last emitted true
    this.obsList = this.obsList.filter(i => i !== lp);
    this.obsListChanged.next(ListAction.Removed);
  }

  isLoading(): Observable<boolean> {
    // return this.progress.pipe(
    //   map(val => val !== 0)
    // );
    return this.obsListChanged.pipe(
      switchMap(() => {
        return combineLatest(this.obsList);
      }),
      map(v => {
        return v.some(loading => loading);
      })
    );
  }
}
export class ProgressService {

  constructor() { }

  progress: Observable<number> = EMPTY; // value > 0 when something is loading

  obsList$: BehaviorSubject<Array<Observable<boolean>>> = new BehaviorSubject<Array<Observable<boolean>>>([]);

  addLoadingProvider(lp: Observable<boolean>) {
    // increment this.progress, when lp emits true
    // decrease this.progress, when lp emits false
    // nice to have: ignore if lp's first emitted value is false
    this.obsList$.next([...this.obsList$.getValue(), lp]);
  }

  removeLoadingProvider(lp: Observable<boolean>) {
    // stop listening to lp
    // clean up: decrease this.progress, if lp last emitted true
    const removed = this.obsList$.getValue().filter(i => i !== lp);
    this.obsList$.next(removed);
  }

  isLoading(): Observable<boolean> {
    // return this.progress.pipe(
    //   map(val => val !== 0)
    // );
    return this.obsList$.pipe(
      switchMap(obs => {
        return combineLatest(obs);
      }),
      map(v => {
        return v.some(loading => loading);
      })
    );
  }
}
枚举列表操作{
补充,
远离的,
空的,,
未定义
}
出口级服务{
构造函数(){}
进度:Observable=EMPTY;//加载时值>0
obsListChanged:BehaviorSubject=新的BehaviorSubject(ListAction.Undefined);
obsList:Array=[];
addLoadingProvider(lp:可观察){
//当lp发出true时,增加this.progress
//当lp发出false时,减少此值。进度
//很好:如果lp的第一个发出值为false,则忽略
此.obsList.push(lp);
this.obsListChanged.next(ListAction.Added);
}
removeLoadingProvider(lp:可见){
//停止听lp
//清理:如果lp上次发出为真,则减少此进度
this.obsList=this.obsList.filter(i=>i!==lp);
this.obsListChanged.next(ListAction.Removed);
}
isLoading():可观察{
//返回此.progress.pipe(
//映射(val=>val!==0)
// );
返回此.obsListChanged.pipe(
开关映射(()=>{
返回CombineTest(此.obsList);
}),
地图(v=>{
返回v.some(加载=>加载);
})
);
}
}
我已经定义了一个ListAction可观察,如果您想按照ListAction执行特定的工作,那么您可以按照逻辑在rxjs操作符中执行相同的操作

方法2[方法1的改进版本]

enum ListAction {
  Added,
  Removed,
  Empty,
  Undefined
}

export class ProgressService {

  constructor() { }

  progress: Observable<number> = EMPTY; // value > 0 when something is loading

  obsListChanged: BehaviorSubject<ListAction> = new BehaviorSubject<any>(ListAction.Undefined);
  obsList: Array<Observable<boolean>> = [];

  addLoadingProvider(lp: Observable<boolean>) {
    // increment this.progress, when lp emits true
    // decrease this.progress, when lp emits false
    // nice to have: ignore if lp's first emitted value is false
    this.obsList.push(lp);

    this.obsListChanged.next(ListAction.Added);
  }

  removeLoadingProvider(lp: Observable<boolean>) {
    // stop listening to lp
    // clean up: decrease this.progress, if lp last emitted true
    this.obsList = this.obsList.filter(i => i !== lp);
    this.obsListChanged.next(ListAction.Removed);
  }

  isLoading(): Observable<boolean> {
    // return this.progress.pipe(
    //   map(val => val !== 0)
    // );
    return this.obsListChanged.pipe(
      switchMap(() => {
        return combineLatest(this.obsList);
      }),
      map(v => {
        return v.some(loading => loading);
      })
    );
  }
}
export class ProgressService {

  constructor() { }

  progress: Observable<number> = EMPTY; // value > 0 when something is loading

  obsList$: BehaviorSubject<Array<Observable<boolean>>> = new BehaviorSubject<Array<Observable<boolean>>>([]);

  addLoadingProvider(lp: Observable<boolean>) {
    // increment this.progress, when lp emits true
    // decrease this.progress, when lp emits false
    // nice to have: ignore if lp's first emitted value is false
    this.obsList$.next([...this.obsList$.getValue(), lp]);
  }

  removeLoadingProvider(lp: Observable<boolean>) {
    // stop listening to lp
    // clean up: decrease this.progress, if lp last emitted true
    const removed = this.obsList$.getValue().filter(i => i !== lp);
    this.obsList$.next(removed);
  }

  isLoading(): Observable<boolean> {
    // return this.progress.pipe(
    //   map(val => val !== 0)
    // );
    return this.obsList$.pipe(
      switchMap(obs => {
        return combineLatest(obs);
      }),
      map(v => {
        return v.some(loading => loading);
      })
    );
  }
}
导出类ProgressService{
构造函数(){}
进度:Observable=EMPTY;//加载时值>0
obsList$:BehaviorSubject=新的BehaviorSubject([]);
addLoadingProvider(lp:可观察){
//当lp发出true时,增加this.progress
//当lp发出false时,减少此值。进度
//很好:如果lp的第一个发出值为false,则忽略
this.obsList$.next([…this.obsList$.getValue(),lp]);
}
removeLoadingProvider(lp:可见){
//停止听lp
//清理:如果lp上次发出为真,则减少此进度
const removed=this.obsList$.getValue().filter(i=>i!==lp);
此.obsList$.next(已删除);
}
isLoading():可观察{
//返回此.progress.pipe(
//映射(val=>val!==0)
// );
返回此.obsList$.pipe(
开关映射(obs=>{
返回组合测试(obs);
}),
地图(v=>{
返回v.some(加载=>加载);
})
);
}
}