#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, я должен был быть немного более ясным с моей точкой зрения выше. Я пытался указать, что ничто в рамках подписки не будет срабатывать до тех пор, пока не произойдет первое действие (событие).