Angular2延迟更新视图

Ang*_*ar2 7 typescript angular

我注意到使用Angular 2的组件有一种奇怪的行为.一旦我的组件改变了作为我的提供者的模型,我的视图需要几秒钟才能更新.即使来自API的数据是单个数据.

例如:

作为我的提供者,我有一个名为UserModel的模型.在我的组件中,我从API获取数据,然后更新此模型,这也在我的视图中.从服务器获得响应之后,更新我的视图仍然需要几秒钟,有时它不会更新,就在我单击同一页面上的任何文本控制器之后,然后在任何文本获得焦点后更新我的视图.

有没有人见过这个?我能做错什么?

卡组件

public createCard(model:CardModel):Promise<any>{
    var context = this;
    return new Promise((resolve, reject) => {
    this.stripe.createToken(model)
        .then(function(token){
            model.token = token;
            context.saveCard("./card", model, true)
                    .then(data => resolve(data))
                    .catch(error => reject(error));
        })
        .catch(error => reject(error));
});
Run Code Online (Sandbox Code Playgroud)

条纹服务

public createToken(model:CardModel):Promise<any>{
    //I get callback and convert return it as promise
    return new Promise((resolve, reject) => {
            //this function is the one from stripe.js, it is not promise
            this.stripe.card.createToken(model, function(status, response){
            if(status == 200){
                resolve(response.id);
            }else{
                reject(response.error.message);
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

如果您发现该函数返回createToken回调,因为它是一个Strip.js功能,然后我把它转换答应还给createCard.但是一旦完成所有功能,我的区域就不会改变.如果我删除this.stripe.card.createToken并使用超时返回一个简单的resolve(),它可以正常工作.所以我认为问题是什么时候有异步函数在Promise中返回回调.但我不知道如何处理它.

eva*_*jmg 0

看来您使用的第三方库不能很好地与 Angular 2 配合使用。我在 StripeJS 上也遇到了同样的问题。该问题与 Angular 的 Zone.js 和 Lifecycle 有关 - 它与 Angular 1 中的错误摘要循环问题非常相似。Angular 在此处提供了有关解决方案的详细文档: https ://angular.io/api/core/ChangeDetectorRef#example-现场演示

为了解决这个问题,您必须实现自己的生命周期循环并将第三方库添加到更改检测中。我对 StripeJS 的实现(还记得用clearInterval销毁setInterval:

import {
  Component,
  Input,
  Output,
  EventEmitter,
  AfterContentInit,
  ChangeDetectorRef,
  ChangeDetectionStrategy,
  ViewContainerRef,
  OnDestroy
} from '@angular/core';

@Component({
  selector: 'v-payment-form', // <payment-form></payment-form>
  changeDetection: ChangeDetectionStrategy.OnPush,
  templateUrl: './payment-form.component.html'
})
export class PaymentFormComponent implements AfterContentInit, OnDestroy {
  checker: any;
  constructor(private changeDetectorRef: ChangeDetectorRef) {
    this.checker = setInterval(() => {
      // the following is required, otherwise the view will not be updated
      this.changeDetectorRef.markForCheck();
    }, 75);
  }
  addPaymentMethod() {
    Stripe.card.createToken(cardDetails)
    this.changeDetectorRef.detectChanges()
  }
  ngAfterContentInit() {
    // ..load stripe js here - I use scriptjs 
  }
  ngOnDestroy(): void {
    clearInterval(this.checker)
  }
}
Run Code Online (Sandbox Code Playgroud)