9 июня 2019 г., 12:10
Методы EditorComponent::canBeParent(parent) и EditorComponent::canBeChild(child)
Всем привет!
Сегодня добавил очень полезные методы в компоненты фронт-редактора - canBeParent(parent) и canBeChild(child). Они предназначены для того, чтобы решать какие компоненты могут быть дочерними или родительскими для других. Это очень важная и полезная функция, так как не всегда отдельные компоненты могут быть вложенными для других. Для примера можно взять EditableObject. К нему прилагаются еще два отдельных компонента - DefaultView и EditableView (они описаны в статье про EditableObject). Изначально было рассчитано, что эти два компонента могут быть добавлены дочерними только непосредственно в EditableObject и больше никуда. В свою очередь в EditableObject могут быть добавлены и любые другие допустимые компоненты. Вот если не учитывать эти правила в визуальном редакторе и никак не ограничивать, то пользователь может какие угодно компоненты добавлять в какие угодно компоненты и в лучшем случае они или не будут работать (или работать неправильно), а в худшем случае возникнет фатальная ошибка. И вот эти методы как раз созданы для решения этой задачи. В DefaultView прописано (как и в EditableView):
То есть для этих компонентов родительскими могут быть только производные от EditableObject и никакие другие. При чем посмотрите внимательней на основные методы:
canBeParent(parent) по умолчанию возвращает parent.canBeChild(this), то есть родителем может быть только тот компонент, для которого этот компонент может быть дочерним, то есть выполняется обоюдная проверка и для родительского компонента, и для дочернего по отношению к нему, что позволяет проверять как в родительском, так и в дочернем.
Напомню, что можно легко в редактор добавляться свои кастомные компоненты и этими методами вы можете всяко рулить иерархию компонентов. Проверки могут быть прописаны какие угодно, включая по уровням доступов отдельных пользователей (к примеру, в этот компонент админы могут дочерние закидывать, а другие пользователи нет), можно по наличию отдельных дочерних компонентов в родительском и т.д. и т.п. (на сколько хватает фантазии).
А в редакторе я сделал, что при перетаскивании нового компонента, у всех имеющихся на странице компонентов, которые не могут быть родительскими для него, пропадает бордер, в результате чего на странице выделенными остаются только те, куда можно бросить новый компонент.
То же самое касается и VerticalTimeline. Для него дочерним может быть только VerticalTimelineItem и никакой более. В свою очередь VerticalTimeline может быть добавлен в любой другой разрешенный компонент.
UPD: Вот получился отличный кейс. На проекте есть различные формы подписок, у которых один и тот же контейнер. Контейнер оформлен в отдельный компонент (потому что если в нем что-то поменяется, должно поменяться для всех форм), а сами формы тоже оформлены в самостоятельные компоненты. При этом без контейнера эти формы не должны существовать, то есть добавить их можно только в такой контейнер. Но тут еще момент: в одном контейнере может находиться только одна форма. То есть если уже есть в нем форма, другую добавить нельзя. Вот как это выглядит в действии: https://youtu.be/2DBusXVlQR4