2016-04-20 4 views
1

私は角2とロダッシュを使って作業しています。角2は、計算されたゲッターにバインドしてデバッグエラーを返します

私が関係を持つモデルを持っていると私はそのようなゲッターがあります:* ngForディレクティブに

編集をrelationsPerTypeの値をバインド

get relationsPerType() { 
    return _(this.Relations) 
     .groupBy(p => p.Type) 
     .toPairs() 
     .map(p => ({ 
      type: <MessageRelationType>p[0], 
      relations: <Relation[]>p[1] 
     })); 
} 

を:

:これは私が結合であります
<div *ngFor="#relationGroup of Message.relationsPerType"> 
    ... 
</div> 

次のエラーが表示されます。

Expression 'Message.relationsPerType in [email protected]:8' has changed after it was checked. Previous

実際には完全に正しいと思われるが、これは、呼び出されるたびに計算される。

どのような場合でも、「計算された」変数を持つと、角2の変化の検出がrelationsPerTypeが実際に変更されたことを検出する方法が想像できません。 ゲッターに不変のマークを付けるようなものがありますか?

私は良い方法は以下のようになりたとします

a)の角度のための変更を追跡しないように、親オブジェクトは不変にするために右の開始

B)からプロパティ内で計算されたゲッター値を格納するにはonプロパティ

これを行うには良い方法はありますか?

+0

どのようにバインドしますか? –

答えて

1

をいくつかの掘削後、私は、デコレータを使用してより良い方法を発見したよりa)及びb)として、提供しています。

a)ゲッタ関数が提供する「怠惰な」計算を緩和し、すべてをプロパティにすることは望ましくありません。

b)は不変で実行可能なソリューションですが、私の場合そう

には適用できない、(PostSharpを参照)C#やアスペクト指向プログラミングの多くから来る、私は最終的にあるキャッシュされたプロパティのゲッターデコレータ関数を作成するために管理一度だけオブジェクトごとに評価:

@cachedProperty 
    get relationsPerType() { 
     return _(this.Relations) 
      .groupBy(p => p.Type) 
      .toPairs() 
      .map(p => ({ 
       type: <MessageRelationType>p[0], 
       relations: <Relation[]>p[1] 
      })).value(); 
    } 
:その後

function cachedProperty(target: any, key: string, descriptor: PropertyDescriptor) { 
    let originalGetter = descriptor.get; 
    descriptor.get = function() { 
     let cachSetted = this[`__cachedsetted${key}`]; 
     if (typeof cachSetted !== 'undefined') { 
      return this[`__cached${key}`]; 
     } 
     this[`__cachedsetted${key}`] = true; 

     return this[`__cached${key}`] = originalGetter.call(this); 
    } 
} 

変更する必要があるのはそうのような、@cachedPropertyデコレータとゲッターを飾るれます10このデコレータを使用すると、オブジェクトは1度しか変更されず、Angular 2依存性注入が不平を言わないようになります。また、私は "怠惰な"評価を失うことはありません、私はスキーマを変更するヘルパープロパティを追加しません。

もちろん、キャッシュが無効になる場合は、キャッシュを無効にしたい場合があります。これを削除する必要があります。

`__cachedsetted${key}` 

プロパティ

0

代わりに値をキャッシュし、キャッシュされた値にバインドするか、データが変更されたときに新しいイベントを発行するオブザーバブルを作成する必要があります。

{{relationsPerType}}にバインドすると、毎回新しいコレクションが作成されます。変更が発生するとAngularは同じデータを含む可能性があるにもかかわらず、2つの異なるインスタンスを取得するため、これを変更と見なします。

calcRelationsPerType() { 
    this relationsPerType = _(this.Relations) 
     .groupBy(p => p.Type) 
     .toPairs() 
     .map(p => ({ 
      type: <MessageRelationType>p[0], 
      relations: <Relation[]>p[1] 
     })); 
} 

はその後、正常に動作する必要があり、このように結合:

<div *ngFor="#relationGroup of Message.relationsPerType"> 
    ... 
</div> 
+0

こんにちは!私はあなたの最初のスニペットにタイプミスがあると思います: 'this relationsPerType = return _(this.Relations)' ;-) –

+0

ThanksGünter。あなたが言うことは、実際には "a)計算されたゲッター値をstartからプロパティーの中に保存する"ことです。データがバインドされる前にcalcRelationsPerType()を呼び出すための多くの努力が必要です。 –

+0

あなたが質問で提供した情報から多大な努力をしているかどうかは分かりません。値が変化するときに再計算される方法を見つける必要があります。解決策を理解するのが最も簡単なのは私の答えに示しているIMHOです。より進んだのは、オブザーバブルを使用することです。デコレータのアプローチも面白いですが、キャッシュの無効化は再計算の呼び出しと非常に似ています。 –

関連する問題