最新のEmberドキュメントによると、オブザーバを使用することは、コンポーネントのライフサイクルフックを無効にすることをお勧めします。私がよく分からないことは、これらのフックを効果的に使う方法です。文書では、オブザーバの代わりにdidUpdateAttrs
とdidReceiveAttrs
を使用することができます。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
の場合は非効率です。
、それを使用することができます。変更されたものを見て、更新が必要かどうかを確認してください... – dandavis
私はそれが 'newAttrs'とおそらく' oldAttrs'を含む 'attrs'という1つの引数を渡したと思います。これら2つをブール値または文字列と比較するのは簡単ですが、オブジェクトの配列はそうではないようです。私はちょうど同じEmber idを持つ2つの配列をチェックし、同じ数のオブジェクトは全く同じオブジェクトのように見えますが、テストでは 'attrs.newAttrs.data === attrs.oldAttrs.data'というテストに失敗します。 – Geoff
不変構造を使用すると比較が容易になります。これらは反応方法論であるため、反応が反応をどのように管理しているかを見てください。また、あなたのユースケースでは観察が簡単になる可能性があります。反応は、浅い方から広い方から深くかつ狭い方が好ましい傾向がある。 – dandavis