Я пишу приложение для создания диаграмм HTML5, используя qooxdoo для системы объектов и набора инструментов для виджетов, а также RaphaelJS в качестве бэкенда для рисования. Модель данных для диаграммы содержит объекты высокого уровня, такие как Item, Line и т. д.; они реализованы как классы qooxdoo со свойствами положения, размеров, цвета и других данных. Каждый класс способен отображать свои экземпляры на бумаге Raphael, скажем, с помощью метода render(). В этот момент создается визуальное («элемент» в терминах Рафаэля).
Проблема в том, что некоторые свойства должны быть установлены до создания визуального элемента 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
}
Есть ли способ сделать то же самое с меньшим количеством шаблонов? Я думал о создании фиктивных «элементов» Raphael для принятия атрибутов стиля до создания фактического элемента и после его создания для передачи фиктивных атрибутов фактическому элементу. Но этот подход, кажется, требует многих изменений в существующем коде. Мне интересно, есть ли более элегантный способ сделать это? Решения на основе АОП приемлемы, так как АОП отлично работает в qooxdoo.