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

#angular #input #debounce #angular-changedetection

#angular #ввод #деблокирование #angular-обнаружение изменений

Вопрос:

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

Вот мой html:

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

и мой ts:

   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 функции.

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

Комментарии:

1. Кажется, это работает для меня (см. Этот stackblitz ).

Ответ №1:

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

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

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

Обратите внимание на консоль.вход в подписку не вызывается.

Поскольку подписка не запускается, внутренний обратный вызов никогда не вызывается. Одним из решений вашей текущей ситуации является назначение значения по умолчанию 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}`)
  }
}
  

Комментарии:

1. Он действительно запускает подписку на (keyup)="debounceSearch.next($event.target.value)" ваш пример, также будет работать, когда вы будете запускать подписку таким же образом stackblitz.com/edit/angular-vxbghl?file=src/app /…

2. @yurzui, я должен был быть немного более ясным с моей точкой зрения выше. Я пытался указать, что ничто в рамках подписки не будет срабатывать до тех пор, пока не произойдет первое действие (событие).