2016-04-08 6 views
2

最新のEmberドキュメントによると、オブザーバを使用することは、コンポーネントのライフサイクルフックを無効にすることをお勧めします。私がよく分からないことは、これらのフックを効果的に使う方法です。文書では、オブザーバの代わりにdidUpdateAttrsdidReceiveAttrsを使用することができます。Emberでのコンポーネントライフサイクルイベントの使用

これで、データをグラフ化するコンポーネントがあるとします。コンポーネントは次のようになります。

{{my-chart data=data showLabels=showLabels otherProps=otherProps}} 

dataが設定されている場合、それはデータ上でいくつかの分析を実行する必要があるので、dataは本当に新しいデータである場合にのみ起こるはず。 showLabels属性は、グラフ内のラベルを表示/非表示し、my-chart以外のものを介して切り替えられます。

私はそれをレンダリングする初期とその後の上で実行するよう didReceiveAttrsを使用することを選択し、それにようなものコーディングされた

:これで問題がdidReceiveAttrs内のすべてのコードは、任意の属性があるたびに実行されていることである

didReceiveAttrs() { 
    let data = this.getAttr('data'); 
    this.performAnalytics(data); 

    let showLabels = this.get('showLabels'); 
    this.updateHideLabels(showLabels); 
} 

をかわった。したがって、ユーザーがshowLabelsを変更するアクションを繰り返し実行すると、performAnalyticsも呼び出されます。これは、チャートが更新されるために悪いことです。

具体的な質問は、didReceiveAttrsのようなライフサイクルイベントをオブザーバーとして使用すると、変更された属性のみがコードパスが実行されるようにするにはどうすればよいですか?

属性を格納してそれを着信属性と比較しようとしましたが、特に複雑なオブジェクトの配列であるdataの場合は非効率です。

+0

、それを使用することができます。変更されたものを見て、更新が必要かどうかを確認してください... – dandavis

+0

私はそれが 'newAttrs'とおそらく' oldAttrs'を含む 'attrs'という1つの引数を渡したと思います。これら2つをブール値または文字列と比較するのは簡単ですが、オブジェクトの配列はそうではないようです。私はちょうど同じEmber idを持つ2つの配列をチェックし、同じ数のオブジェクトは全く同じオブジェクトのように見えますが、テストでは 'attrs.newAttrs.data === attrs.oldAttrs.data'というテストに失敗します。 – Geoff

+1

不変構造を使用すると比較が容易になります。これらは反応方法論であるため、反応が反応をどのように管理しているかを見てください。また、あなたのユースケースでは観察が簡単になる可能性があります。反応は、浅い方から広い方から深くかつ狭い方が好ましい傾向がある。 – dandavis

答えて

0

ユーティリティファイル、たとえばutils/component-lifecycle.jsを書き込むことができます。

export const attrsHaveChanged = ((changes, attr) => { 
    const { oldAttrs, newAttrs } = changes; 
    if (oldAttrs) { 
    const oldAttrsValue = JSON.stringify(oldAttrs[attr].value); 
    const newAttrsValue = JSON.stringify(newAttrs[attr].value); 
    return oldAttrsValue !== newAttrsValue; 
    } else { 
    return true; 
    } 
}); 

、今お使いのコンポーネント内で、あなたは、

import { attrsHaveChanged } from 'appname/utils/component-lifecycle'; 

それをインポートして、関数が2つの引数、 `(oldAtrs、newAttrsを)`渡され

didReceiveAttrs(changes) { 
    if (attrsHaveChanged(changes, 'chartData')) { 
    doSomething(); 
    } 
} 
関連する問題