2016-08-31 13 views
5

角度2を使用してコンポーネントで奇妙な動作が検出されました。 コンポーネントがモデルに変更を加えたら、ビューが更新されるまでに数秒かかります。 APIからのデータが単一のデータであっても。例えばビューを更新するための角度2の遅延

私は私のプロバイダとしての私のコンポーネント内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)); 
}); 

ストライプサービス

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); 
      } 
     }); 
    }); 
} 

それはStrip.js機能であるため、あなたはcreateTokenがコールバックとして返す関数に気づき、その後、私はそれはそれを返すことを約束して変換する場合カードを作成する。しかし、すべての機能が完了すると、ゾーンは変更されません。 this.stripe.card.createTokenを削除してタイムアウトを使用して簡単なresolve()を返すと、正常に動作します。だから私は問題がPromiseの中でコールバックを返す非同期関数を持っていると信じています。しかし、私はそれに対処する方法を知りません。

+0

Angularsゾーン外で実行いくつかのコードは、データを更新するとこれが通常でないコールバックを持つ一部のAPI。 –

+0

いくつかのコードを追加して質問を更新しました – Angular2

+0

'Promise'はいくつかのpolyfillに依存するかもしれません。あなたがObservableを使っているなら、それは間違いなく働くはずです。ぞっとする。 –

答えて

0

Angular 2でうまく動作しないサードパーティのライブラリを使用しているようです。私はStripeJSでも同じ問題がありました。この問題は、Angular's Zone.jsおよびLifecycleに関連しています。Angularは、Angular 1の悪いダイジェストサイクルの問題によく似ています。https://angular.io/api/core/ChangeDetectorRef#example-live-demo

これを解決するには、独自のライフサイクルループを作成し、サードパーティライブラリを変更検出に追加します。 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) 
 
    } 
 
}

関連する問題