Как связать подписку на BehaviorSubject ‹boolean›?

У меня есть приложение Angular, которое показывает и скрывает поле ввода в зависимости от содержимого другого поля ввода. Теперь мне нужно выполнить автоматическое форматирование второго поля, когда пользователь что-то вводит в него. Но поле скрыто при загрузке компонента, поэтому мне нужно проверить значения первого поля, чтобы проверить, должно ли отображаться второе, а затем, когда оно станет видимым, подписаться на его valueChanges.

Мой код выглядит так:

export class MyInputComponent implements AfterViewInit {
  private subscription = Subscription.EMPTY;

  @ViewChild('firstInput', { read: NgControl }}
  public firstInput: NgControl;

  @ViewChild('secondInput', { read: NgControl }}
  public secondInput: NgControl;

  public isSecondInputVisible = new BehaviorSubject<boolean>(false);

  public ngAfterViewInit() {
    this.firstInput.valuesChanges!.subscribe((first) => {
      this.isSecondInputVisible.next(first.length > 4);
    });

    this.isSecondInputVisible.subscribe((isVisible) => {
      if (isVisible) {
        this.subscription = this.secondInput.valueChanges!.subscribe((value) => {
          // do something...
        });
      } else {
        this.subscription.unsubscribe();
      }
    });
  }
}

Мне было интересно, есть ли способ связать подписки, у меня не будет слишком много отступов и вложений в коде. Я думал, что это возможно с помощью pipe, но пока не нашел способа.

Есть ли способ оптимизировать подписку?


person Community    schedule 31.08.2018    source источник


Ответы (1)


Вы можете использовать concatMap и внутри него вернуть empty(), если поле невидимо.

this.isSecondInputVisible
  .pipe(
    concatMap(isVisible => isVisible
      ? this.secondInput.valueChanges!
      : empty()
    )
  )
  .subscribe(valueChanged => /* do something...*/)
person martin    schedule 31.08.2018
comment
Это лучше, чем конструкция if, которую я получил. Спасибо. - person ; 31.08.2018
comment
О, мне интересно: если второе поле будет скрыто, будут ли Angular / RxJs автоматически отказываться от подписки? Вот почему я явно отказался от подписки в своем блоке else. - person ; 31.08.2018