Javascript 角度5视图在超时后不更新
我正在设置一个超时,以便在Angular 5中隐藏一个元素:Javascript 角度5视图在超时后不更新,javascript,angular,asynchronous,Javascript,Angular,Asynchronous,我正在设置一个超时,以便在Angular 5中隐藏一个元素: this.showElement = true; setTimeout(function () { console.log('hide'); this.showElement = false; }, 2000); 但是,这不会更新视图。console.log为我提供了一个输出,因此超时确实有效 我发现在Angularjs中,你需要调用$apply来开始一个摘要,所以我猜我只需要找到Angularjs的5种等效方法。更新:正确
this.showElement = true;
setTimeout(function () {
console.log('hide');
this.showElement = false;
}, 2000);
但是,这不会更新视图。console.log
为我提供了一个输出,因此超时确实有效
我发现在Angularjs中,你需要调用
$apply
来开始一个摘要,所以我猜我只需要找到Angularjs的5种等效方法。更新:正确答案。
正如其他人正确回答的那样,未反映更改的原因是对此引用的引用不正确
请注意,当使用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箭头表示法,会将此
引用的上下文更改为父上下文。所以
myFunction() {
this.showElement = true;
setTimeout(() => {
console.log(this.showElement); // Will result in true;
this.showElement = false; // Here, value is updated
}, 2000);
}
当您使用函数样式“this”引用不起作用时,请阅读有关词法this
的更多信息
像下面这样做,您的示例将正确运行
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
我认为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
回调函数。我在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>
setTimeout(function () {
console.log('hide');
this.showElement = false;
}.bind(this), 2000);
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
在timeout函数中添加this.cd.markForCheck()解决了我的问题
早些时候,@artemisian在您的构造函数中,添加了一个变更检测器,对其进行了评论:
constructor(private cd: ChangeDetectorRef) {}
然后在设置超时时:
它正在更新值,但问题在于此
。您可以通过bind或arrow函数设置该值
setTimeout(function () {
console.log('hide');
this.showElement = false;
}.bind(this), 2000);
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
或者我们可以使用arrow函数,因为它的这个值是包含函数的setup
setTimeout(function () {
console.log('hide');
this.showElement = false;
}.bind(this), 2000);
this.showElement = true;
setTimeout(() => {
console.log('hide');
this.showElement = false;
}, 2000);
您不需要进行更改检测,甚至不需要超时,只要将this.showElement双向绑定到元素本身上的*NgIf,它就会根据需要删除并显示它。当心超时使用,它可能会消耗资源,如果你想让应用程序通用,它会杀死你的应用程序。要补充的一点是,在Angular 1.x中,有一个$timeout服务你会使用。在Angular 2+中,没有$timeout服务。如果您希望保留组件/服务上下文的词法范围,则最好/建议使用arrow函数。如果在Ionic 4中存在相同的问题,这是正确的解决方案。