Угловое представление 5 без обновления после таймаута
Я устанавливаю таймаут, чтобы скрыть элемент через некоторое время в Angular 5:
this.showElement = true;
setTimeout(function () {
console.log('hide');
this.showElement = false;
}, 2000);
Однако это не обновляет представление. console.log
дает мне выход, поэтому тайм-аут определенно работает.
Я обнаружил, что в Angularjs вам нужно было называть $apply
, чтобы начать дайджест, поэтому я предполагаю, что мне просто нужно найти эквивалентный способ Angular 5.
Ответы
Ответ 1
Я думаю, что обратный вызов setTimeout
теряет область видимости для переменной "showElement".
this.showElement = true; // this - is in component object context
setTimeout(function () {
console.log('hide');
this.showElement = false; // here... this has different context
}, 2000);
Вы должны использовать функцию стрелки:
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
Или используйте bind
:
this.showElement = true;
setTimeout(function() {
console.log('hide');
this.showElement = false;
}.bind(this), 2000);
для передачи правильного контекста функции обратного вызова setTimeout
.
Ответ 2
Обновлено: Исправлен ответ.
Как правильно ответили другие, причина, по которой изменения не отражаются, связана с неправильной ссылкой на this
ссылку.
Обратите внимание, что при использовании обозначения function() {... }
ссылка на this
- это контекст самой функции. Так
myFunction() {
this.showElement = true;
setTimeout(function() {
console.log(this.showElement); // Will result in undefined;
this.showElement = false; // Here, this, reference to context of the function wrapper
}, 2000);
}
Изменив приведенное выше на обозначение стрелки ES6, измените контекст this
ссылки на родительский контекст. Так
myFunction() {
this.showElement = true;
setTimeout(() => {
console.log(this.showElement); // Will result in true;
this.showElement = false; // Here, value is updated
}, 2000);
}
Подробнее о lexical this
читайте здесь.
Ответ 3
когда вы используете стиль функции, эта "ссылка" не работает, как это выглядит, и ваш пример будет работать правильно
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
Ответ 4
Я столкнулся с той же проблемой в моем приложении Angular 7. Мне пришлось изменить источник заголовка и значок в кнопке:
<button class="btn btn--outline-red text-uppercase font-weight-normal product-action-btn mt-3"
(click)="addToCart()">
{{addToCartProps.title}}
<img style="width:15px; height:15px;" [src]="addToCartProps.src">
</button>
.......
addToCartProps = { title: 'Add to Cart', src: '' }
addToCart() {
this.addToCartProps.title = 'Adding';
this.addToCartProps.src = 'assets/images/preloader-white.svg';
setTimeout(() => {
this.addToCartProps.title = 'Added';
this.addToCartProps.src = 'assets/images/checked-icon-white.svg';
this.cd.markForCheck();
console.log('timeout 1 ', this.addToCartProps);
}, 1000);
setTimeout(() => {
this.addToCartProps.title = 'Add to cart';
this.addToCartProps.src = '';
this.cd.markForCheck();
console.log('timeout 2 ', this.addToCartProps);
}, 1500);
}
Добавление this.cd.markForCheck() в функцию тайм-аута решило проблему в моем случае.
Ранее это также прокомментировал @artemisian в Angular2, представление не обновляется после изменений переменных в settimeout
Ответ 5
В своем конструкторе добавьте детектор изменений:
constructor(private cd: ChangeDetectorRef) {}
А затем в вашем setTimeout:
setTimeout(() => {
console.log('hide');
this.showElement = false;
this.cd.detectChanges();
}, 2000);