Содержание

Паттерн "владелец" (owner)

Паттерн "владелец" используется экземплярами basis.dom.wrapper.AbstractNode (и его потомками), для ограничения числа объектов, которые влияют на экземпляр и/или на которые он влияет. Так экземпляр может иметь максимум одного владельца.

Данный паттерн утилизируется сателлитами, экземплярами GroupingNode (см Группировка) и другими.

Принцип работы

Экземпляры хранят ссылку на своего владельца в свойстве owner. В качестве значения может быть экземпляр basis.dom.wrapper.AbstractNode или null. Значение задается либо при создании, либо вызовом метода setOwner(newOwner) в дальнейшем. При изменении владельца (изменении свойства owner), выбрасывается событие ownerChanged(oldOwner), где oldOwner значение свойства owner до изменения.

Владелец может ничего не знать об объектах, для которых является владельцем, но чаще имеет ссылку на такие объекты. Например, экземпляры basis.ui.Node хранит ссылку на группирующий узел в свойстве grouping, а на именованные сателлиты – в свойстве satellite.

Обычно с разрушением владельца разрушается и сам объект, если эта логика не переопределена.

Для упрощения добавления обработчика событий владельца можно использовать свойство listen.

parentNode vs. owner

У узла может быть установлен либо родительский узел (свойство parentNode), либо владелец (свойство owner). При вызове методов, которые меняют parentNode (методы appendChild, insertBefore, replaceChild, setChildNodes) при установленном owner (не равным null) выбрасывается исключение. То же самое происходит при вызове методов меняющие свойство owner (методы setOwner, setSatellite) при установленном parentNode.

Наличие значений для обоих свойств parentNode и owner создает конфликтные ситуации, когда родитель и владелец одновременно влияют на узел или узел заимствует некоторые данные из родителя или владельца. Так же это делает возможным из древовидной иерархии объектов получить граф содержащий циклы, что может привести к рекурсии и неоднозначности.

Чтобы дойти от узла к корню иерархии, нужно переходить по ссылке parentNode либо owner.

var cursor = node;

while (cursor.parentNode || cursor.owner)
  cursor = cursor.parentNode || cursor.owner;

console.log(cursor, 'is root of', node);