我正在尝试基于(core)、(tapestry5-jquery) 和(tapestry5-jquery) 组件以及AJAX 更新构建一个名为CrudEntityField的 Tapestry 组件。TextField
DialogLink
Dialog
Zone
我的用例很简单:
CrudEntityField 将呈现为 TextField。如果您知道实体 ID,则可以直接在此处输入。如果不知道id,可以点击
DialogLink
按钮(SELECT),弹出Dialog窗口。对话框以表格形式列出所有可用的实体,并让我们按一些标准进行过滤。一旦用户选择了实体,文本字段就会自动刷新相关的id(例如'6')。此外,为了清楚起见,还打印了相关的名称/描述(例如,“[Gipuzkoa]”)。快照:CrudEntityField,弹出对话框
理想情况下,所有这些逻辑都可以封装在一个Tapestry组件中。但是问题来了:
对话框(
<div t:type="jquery/dialog" t:clientId="dialogIdXXX">
见下文)包括一个搜索表单,并且它本身嵌入在另一个表单(CRUD 表单)中。由于不允许嵌套表单,我可以尝试取消嵌套它。但是,这种方法会失败,因为在我有机会移动它之前,在呈现内部表单时会出现运行时异常。@AfterRender public void afterRender(MarkupWriter writer) { Element body = writer.getDocument().find("html/body"); writer.getDocument().getElementById("dialogIdXXX").moveToBottom(body); }
我尝试了其他方法,例如
@HeartbeatDeferred
,RenderCommand
等,但我发现无法将对话框呈现在表单之外。
组件模板:
<t:content>
<!-- A) Entity Field -->
<t:zone t:id="entityZone" id="zoneIdXXX">
<div class="inputElement">
<t:label for="textField"/>
<input t:id="textField"/>
[<t:body/>]
<t:jquery.dialoglink t:dialog="dialogIdXXX" class="dialogLink">SELECT</t:jquery.dialoglink>
</div>
</t:zone>
<!-- B) Entity Dialog -->
<div t:type="jquery/dialog" t:clientId="dialogIdXXX" params="params" >
<table t:id="xa2grid" t:entity="inherit:entity" t:add="actions">
<p:actionsCell>
<a t:type="EventLink" t:event="SELECT" t:zone="zoneIdXXX" t:context="entity.id" href="#">SELECT</a>
</p:actionsCell>
</table>
</div>
</t:content>
好的,所以我可以将组件分成两部分:(
EntityField
表单输入字段)和EntityDialog
(放置在表单之外,在页面模板中)。但是,并不优雅,因为这种方法打破了抽象。但这种方法也行不通。zone 事件现在由
EntityDialog
组件触发,并且必须由其自身或其容器之一处理。但是该区域是在 中定义的EntityField
,现在是兄弟!(如果不清楚,我可以粘贴更多代码)。