#angular
#angular
Вопрос:
Пример:
@Component({
selector: "app-ex3-component-a",
templateUrl: "./ex3-component-a.component.html",
styleUrls: ["./ex3-component-a.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class Ex3ComponentAComponent implements OnInit
{
public config = {title: "Initial title."};
public interval: Subscription;
constructor() { }
public ngOnInit(): void
{
}
public changeTitle()
{
if (this.interval)
{
this.interval.unsubscribe();
this.interval = null;
return;
}
this.interval = interval(300)
.pipe(
map(() => ({...this.config, title: `From A (${Math.floor(Math.random() * 1000)})`})),
tap((newConfig) => this.config = newConfig),
tap(() => console.log(this.config.title))
).subscribe();
}
}
HTML:
<p>config.title={{config.title}}</p>
<button (click)="changeTitle()">{{interval ? "Stop" : "Start changing"}}</button>
Что происходит:
- каждые 300 мс в консоли отображается новое значение
- пользовательский интерфейс изменяется только при остановке интервала
- если я установлю интервал, например, равным 3 секундам, произойдет то же самое
Я ожидаю, что пользовательский интерфейс будет обновлен так же, как и консоль, но этого не происходит.
Ответ №1:
Это потому, что при использовании onPush
angular ищет изменения в Input
параметрах.
Подробнее: onpush-change-detection-how-it-works
Вы можете обнаружить изменения вручную (это рекомендуемый способ) следующим образом:
constructor(private cdr: ChangeDetectorRef)
this.interval = interval(300)
.pipe(
map(() => ({...this.config, title: `From A (${Math.floor(Math.random() * 1000)})`}))
).subscribe(newConfig => {
this.config = newConfig;
this.cdr.detectChanges();
console.log(this.config.title);
});
- Имейте в виду, что код не тестировался, возможно, в нем есть некоторые опечатки, но основная идея верна.
Комментарии:
1. зависимость «ChangeDetectorRef» от @angular / core, спасибо за ваш быстрый ответ!