обнаружение изменений не работает при отклонении углового ввода

У меня есть ввод и по дебаусу (через полсекунды после окончания набора текста) ставлю переменную. Я хочу, чтобы эта переменная изменила некоторый html. Это работает, но только после того, как я закончу печатать, затем наберу и начну снова. Так что со второго раза все работает. Я бы хотел, чтобы это произошло в первый раз.

Вот мой html:

  <loader *ngIf="searchLoader"></loader>
  <input
    #searchInput
    placeholder="Search pages"
    [(ngModel)]="searchQuery"
    (keyup)="debounceSearch.next($event.target.value)"
  >

и мой ТС:

  debounceSearch: Subject<any> = new Subject<any>();

  ngOnInit() {
    this.debounceSearch
      .pipe(debounceTime(500))
      .pipe(takeUntil(this.destroy$))
      .subscribe(() => {
        this.searchLoader = true;
        this.searchDocs();
      });
  }

Таким образом, в приведенном выше примере <loader></loader> появляется только после второго устранения дребезга. Это странно, потому что я сразу же установил переменную в значение true.

  • debounceTime исходит из оператора rxjs import { debounceTime, takeUntil } from "rxjs/operators";, по существу, через заданное время (500 мс) он запускает то, что когда-либо было в функции .subscribe.

Я пытался использовать ссылку детектора изменений и обнаруживать изменения в функции подписки, но у меня это не сработало.


person cup_of    schedule 13.04.2019    source источник
comment
Кажется, это работает для меня (см. этот stackblitz).   -  person ConnorsFan    schedule 14.04.2019


Ответы (1)


Проблема здесь в том, что вы пытаетесь присвоить значение, когда еще ничего не вызвало Subscription.

Возьмите этот пример на StackBlitz. Если вы откроете журнал консоли, вы увидите это в следующем порядке

  • ngOnChanges вызывается
  • Вызывается ngOnInit.
  • включение не определено

Обратите внимание, что console.log внутри подписки не вызывается.

Поскольку ничто не запускает подписку, внутренний обратный вызов никогда не вызывается. Одним из решений вашей текущей ситуации является назначение по умолчанию this.searchLoader = true or false; за пределами ngOnInit

@Component({
  selector: 'hello',
  template: `
    <h1>Hello {{name}}!</h1>
    <p *ngIf="turnOn">I'm a ninja</p>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent implements OnInit  {
  @Input() name: string;

  turnOn: boolean;
  switchSubject: Subject<any> = new Subject<any>();

  ngOnChanges() {
    console.log('ngOnChanges called.');
  }

  ngOnInit() {
    console.log('ngOnInit called.');
    this.switchSubject.subscribe(() => {
      console.log('subscription activated.');
      this.turnOn = true;
    })
    console.log(`turnOn is ${this.turnOn}`)
  }
}
person davidb    schedule 14.04.2019
comment
На самом деле он запускает подписку через (keyup)="debounceSearch.next($event.target.value)". Ваш пример также будет работать, когда вы активируете подписку таким же образом stackblitz.com/edit/angular-vxbghl?file=src/app/ - person yurzui; 14.04.2019
comment
@yurzui, я должен был быть более ясным в своей точке зрения выше. На что я пытался указать, так это на то, что в рамках подписки ничего не сработает, пока не произойдет первое действие (событие). - person davidb; 14.04.2019