Поверхностное диалоговое окно 'appendTo' свойство, для чего оно полезно?
Возможно, это тупой вопрос, но в Primefaces <p:dialog>
есть свойство, которое называется appendTo
, которое описано в руководстве как:
Добавляет диалог к элементу, определенному данным поиском выражение.
Я не могу понять, для чего это полезно?
Ответы
Ответ 1
Из Руководство пользователя PrimeFaces (на данный момент стр. 185):
Не размещайте диалог внутри таблиц, контейнеры любят divs с относительным позиционированием или с невидимыми переполнение, в таких случаях, как эта функция может быть нарушена. Это не ограничение а результат модели DOM. Например, диалог внутри блока макета, табуляция, аккордеон - это несколько примеров. То же самое относится и к confirmDialog.
Вы можете преодолеть это, используя appendTo="@(body)"
, и ваш dialog
будет прикреплен как дочерний элемент <body>
node.
Один из основных параметров dialog
- modal
, и вы можете быстро завершить свой диалог за оверлей, если вы не используете appendTo
, как показано ниже:
![enter image description here]()
См. также http://forum.primefaces.org/viewtopic.php?f=3&t=16504
Примечания:
Ответ 2
Документы PrimeFaces на данный момент немного разрежены. appendToBody
/appendTo
(до 5.0) решает (или пытается решить) проблему, при которой компонент PrimeFaces не получает нужный z-индекс, то есть он не появляется перед или за другими элементами так, как должен. Однако эта функция проблематична, поскольку она может вызвать другие проблемы.
TL;DR:
Не используйте appendTo
/appendToBody
. Вместо этого диалоговые окна (вместе с ConfirmDialog и OverlayPanel) всегда должны располагаться в верхней части иерархии компонентов, как прямой потомок <h:body>
. Это заставит их работать надежно. В этом случае использование appendTo
/appendToBody
не требуется.
Одним из хороших способов добиться этого является наличие одного (или нескольких) отдельных файлов XHTML для этих компонентов ( "dialogs.xhtml" ), который затем включается в основной файл XHTML или шаблон (например, используя <ui:include>
).
Подробнее читайте: -)
Проблема
Некоторые компоненты PrimeFaces (такие как диалоги) должны отображаться поверх других элементов.
Например:
Если вы используете <p:dialog ...modal="true">
и сделаете диалог видимым, вы получите диалог на переднем плане, появляющийся над остальной частью страницы, с остальной частью страницы, покрытой прозрачным слоем.
Вы можете увидеть это, например, в PF Showcase для диалогов (кнопка "Модаль" ).
За кулисами, т.е. на странице DOM, происходят две вещи:
- в конце
<body>
создается новый <div>
( "модальный оверлей" ). Этот div получает стили CSS: z-index: 1000; position: absolute; opacity: .30;
. Это делает его прозрачным и охватывает всю страницу, чтобы получить "модальный" эффект.
- (существующий, но невидимый) div самого диалога становится видимым и получает стиль
z-index: 1001; position:fixed;
. Обратите внимание, что z-индекс больше, чем модальный наложение, поэтому диалог появляется над надписью.
Однако, это не всегда работает. Причиной этого является аспект CSS, называемый
Как объяснялось выше, проблема возникает из-за того, что HTML, отображаемый для компонента PrimeFaces, находится где-то глубоко в DOM, в то время как для нормального z-индекса должен быть прямой дочерний элемент <body>
.
Когда используется appendToBody
/appendTo
, PrimeFaces будет включать Javascript на отображаемой странице, которая просто перемещает DOM node компонента PrimeFaces в конец <body>
(используя JQuery ). Таким образом, компонент находится в нужном месте в DOM, и работает z-index.
В то время как реорганизация DOM, выполняемая appendTo
, решает проблему с CSS и z-index, она вводит другую (потенциальную) проблему:
Клиентская сторона DOM больше не соответствует состоянию страницы на стороне сервера, поддерживаемой JSF (называемой представлением).
Теперь одна из центральных особенностей JSF заключается в том, что он ожидает, что структура HTML/DOM на стороне клиента будет соответствовать представлению на стороне сервера. В конце концов, JSF построил HTML из этого представления. Если это правило нарушено (как правило, путем манипулирования клиентской стороной DOM), вы получаете всевозможные странные проблемы, такие как JSF, игнорирующий поля формы или значения в передаче или перезаписи части ваших изменений в обновлениях AJAX.
В этом случае проблемы, вызванные перемещением DOM node компонента PrimeFaces, включают:
Если компонент PrimeFaces является частью <h:form>
, он не будет работать должным образом (потому что он не будет находиться внутри тега <form>
на стороне клиента из-за перемещения).
Это фактически упоминается в документах PrimeFaces вместе с обходным решением: вместо того, чтобы поместить компонент в форму, поместите форму внутри компонента - тогда форма будет перемещаться вместе с компонентом.
Если область, в которой JSF изначально представляла компонент PrimeFaces, обновляется с использованием функции JSF AJAX, JSF удаляет область для обновления из DOM, а затем снова отображает компонент, поскольку он не знает, что он перемещен в другом месте.
В старых версиях PrimeFaces это заставляло компонент отображаться в DOM дважды (с тем же id
), что вызвало проблемы с последующими отправлениями. Это было исправлено для PrimeFaces 4.0 (), но снова произошел в 5.0 ( ).
Это показывает, что этот вид манипуляции DOM "за спиной JSF" довольно рискован и его следует избегать, поэтому мой совет не использовать appendTo
/appendToBody
.