Паттерн "владелец" используется экземплярами 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
), либо владелец (свойство 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);