オブジェクト システムとウィジェット ツールキットに qooxdoo を使用し、描画バックエンドとして RaphaelJS を使用して、HTML5 ダイアグラム アプリケーションを作成しています。ダイアグラムのデータ モデルには、Item、Line などの高レベル オブジェクトが含まれています。これらは、位置、寸法、色、その他のデータのプロパティを持つ qooxdoo クラスとして実装されます。各クラスは、たとえば render() メソッドを使用して、そのインスタンスを Raphael 紙にレンダリングできます。この時点で、ビジュアル (Raphael の用語では「要素」) が作成されます。
問題は、 Raphael ビジュアルを作成する前にいくつかのプロパティを設定する必要があることです。Raphael では、中心座標と半径を指定しないと円を描くことができません。パス定義なしでパスを作成することはできません。実際のテキストなしでテキスト ラベルを作成することはできません。さらに、一部のプロパティは、ビジュアルの作成後にのみ設定できます。存在しないビジュアルの色、ストローク スタイルなどを設定することはできません。したがって、次のワークフローを想像できます。
var circle = new my.Circle();
circle.set({ x: 10, y: 20, r: 30 }); // can't set color here - no visual yet
circle.render(paper);
circle.set({ stroke: "red", strokeWidth: 5 });
オブジェクトを手動で作成すると、このワークフローを制御できます。しかし、シーン グラフ全体が (保存されたダイアグラムを読み込むために) JSON からアンマーシャリングされている場合、呼び出しのシーケンスを制御することはできず、すべてのプロパティが一度に設定されます。そのため、私の Circle クラスのmembers
セクションには次のものが含まれています。
// Setter for stroke
_applyStroke: function(val, old) {
this.element && this.element.attr({ stroke: val });
}
// The same for fill, stroke width, stroke style, arrowhead style etc.
// ...
render: function(paper) {
this.element = paper.circle(this.getX(), this.getY(), this.getR());
this._applyStroke(this.getStroke());
this._applyStrokeWidth(this.getStrokeWidth());
// repeat for each style property
}
ボイラープレートを少なくして同じことをする方法はありますか? 実際の要素が作成される前にスタイル属性を受け入れ、作成後にダミーの属性を実際の要素にコミットするために、ダミーのラファエル「要素」を作成することを考えていました。しかし、このアプローチでは、既存のコードに多くの変更を加える必要があるようです。これを達成するためのよりエレガントな方法があるかどうか疑問に思っていますか? AOP は qooxdoo でうまく機能するため、AOP ベースのソリューションは受け入れられます。