简体   繁体   English

即使评估为真,带复选框的 TakeUntil 也会阻止流

[英]TakeUntil with Checkbox Blocks Stream Even When Evaluation is True

I'm trying to use takeUntil to stop a stream once a checkbox is switched off.一旦复选框被关闭,我正在尝试使用takeUntil来停止流。 I'm in Angular so for now I'm just concatenating a sting on a class property, not worrying about concatenating results of observables yet.我在 Angular 中,所以现在我只是在类属性上连接一个刺,而不用担心连接可观察的结果。

this.checked$ is a BehaviorSubject that starts false and gets next ed when my checkbox is de/activated. this.checked$是一个BehaviorSubject ,当我的复选框被取消/激活时,它开始为false并获得next ed。 That part is for sure working at least somewhat because below will start to display the dots.那部分肯定至少在某种程度上起作用,因为下面将开始显示点。 However, adding the (commented out below) takeUntil(this.checked$) results in no dots displaying at all.但是,添加(在下面注释掉) takeUntil(this.checked$)导致根本不显示点。

const source$ = interval(250).pipe(mapTo("."));
this.checked$
.pipe(
  filter(c => {
    return c === true;
  }),
  switchMap(() => {
    console.log("switchMap");
    // return source$.pipe(takeUntil(this.checked$));
    return source$;
  })
)
.subscribe(data => {
  console.log("in subscribe", data, this.dots);
  this.dots += data;
});

What is incorrect about how I am using BehaviorSubject and takeUntil here?我在这里使用BehaviorSubjecttakeUntil什么不正确?

Here is a full example is on StackBlitz . 这是 StackBlitz 上的一个完整示例

Note that takeUntil emits values only until the first checked$ is emited, here are good examples.请注意, takeUntil仅在发出第一个checked$之前发出值, 这里有很好的例子。 Because checked$ is a BehaviorSubject it emits the current value immediately when you subscribe to it, as a result takeUntil stops.因为checked$是一个BehaviorSubject它会在您订阅它时立即发出当前值,因此takeUntil停止。

A solution might be to switch between source$ and an empty observable inside the switchMap, like:一个解决方案可能是在source$和 switchMap 中的一个空的 observable 之间切换,比如:

const source$ = interval(250).pipe(mapTo("."));
this.checked$
  .pipe(
    switchMap(c => {
      console.log("switchMap");
      return c ? source$ : EMPTY;
    })
  )
  .subscribe(data => {
    console.log("in subscribe", data, this.dots);
    this.dots += data;
  });

StackBlitz example StackBlitz 示例


You can also fix your original solution by skipping the first value of checked$ subject, but I recommend you the previous solution because it's simpler.您也可以通过跳过checked$主题的第一个值来修复您的原始解决方案,但我建议您使用以前的解决方案,因为它更简单。

const source$ = interval(250).pipe(mapTo("."));
this.checked$
  .pipe(
    filter(c => {
      return c === true;
    }),
    switchMap(() => {
      console.log("switchMap");
   // return source$.pipe(takeUntil(this.checked$));
      return source$.pipe(takeUntil(this.checked$.pipe(skip(1))));
    })
  )
  .subscribe(data => {
    console.log("in subscribe", data, this.dots);
    this.dots += data;
  });

StackBlitz example StackBlitz 示例


Another solution is to use Subject instead of BehaviorSubject .另一种解决方案是使用Subject而不是BehaviorSubject The difference is that the Subject doesn't hold current value and emits nothing when you subscribe to it.不同之处在于, Subject不持有当前值,并且在您订阅它时不会发出任何内容。 It emits only when next() is called.它仅在调用next()时发出。 If you replace BehaviorSubject with Subject in your original solution, it will work as expected.如果在原始解决方案中将BehaviorSubject替换为Subject ,它将按预期工作。

StackBlitz example StackBlitz 示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM