Tapestry5:具有类似 page-loop-customComponent-form 结构的页面不起作用
我有以下情况: 我有在某些上下文中激活的页面(例如“/page/ctx1”) 我有通过 t:loop 插入页面的组件 DayJournalItem
<div t:type="Loop" t:source="journalDays" t:value="journalDay"
t:encoder="dayEncoder"><t:DayJournalItem day="journalDay"
cacheContainer="cacheContainer" /></div>
并且 DayJournalItem 与其他组件 ActivityJournalItem 有另一个循环,该组件具有
<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
<t:zone t:id="dayAjaxZone" update="show">
<div class="dayHeader">${dayHeader}</div> <div class="dayBody">
<div t:type="Loop" t:source="activities" t:value="activity"><t:ActivityJournalItem
activity="activity" cacheContainer="cacheContainer" /></div>
</div>
</t:zone></div>
ActivityJournalItem 组件
<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
<t:zone t:id="activityAjaxZone" update="show">
<t:if test="${editingActivity}">
<div class="activityEditFormBody">
<form t:type="form" t:id="activityForm" t:zone="activityAjaxZone">
....
<input t:id="Save" t:type="Submit" value="Save" />
<input t:id="Cancel" t:type="Submit" value="Cancel" />
</form>
</div>
</t:if>
<t:if test="${!editingActivity}">
<div>viewing activity: ${activity.id}</div>
</t:if>
</t:zone></div>
形式问题是 - 当我按下提交按钮时出现 NullPointerException。我的自定义组件中的所有字段均为空。 Tapestry 似乎无法正确恢复上下文。您可以在此处查看屏幕截图: http://my.jetscreenshot.com/2672 /20100807-tbfe-235kb.jpg
我想我在表单、循环或其他地方丢失了一些参数。并且无法弄清楚出了什么问题。顺便说一句,我尝试使用编码器,但 Tapestry 事件不调用它们 - 似乎它们只在表单内工作。但我有循环内的形式。 因此,非常感谢任何帮助。
ps如果您需要更多详细信息,您可以查看完整的源代码(在谷歌代码): http://code.google.com/p/tasks-journal/source/checkout
UPD:我发现我可以将 t:context 传递到表单,并且在 onPrepareForSubmit 阶段我可以手动恢复字段(通过相当肮脏的解决方法)。好吧,现在没有 NPE,但是: 1. 这很丑; 2. 这不会导致表单重新渲染。没有异常,也没有按预期重新渲染。我检查了 HTTP 响应,只有空括号 =“{}”
UPD2:我仍在尝试糟糕的解决方法。我发现如果我在 onSuccess 中会“返回这个;”然后将发生重新渲染。但是(!)它总是重新渲染页面上的第一个表单(或区域?)。 http://my.jetscreenshot.com/2672/20100808-thdx-190kb。 jpg
I have the following situation:
I have Page which activated in some context (for example "/page/ctx1")
I have component DayJournalItem which inserted in page via t:loop
<div t:type="Loop" t:source="journalDays" t:value="journalDay"
t:encoder="dayEncoder"><t:DayJournalItem day="journalDay"
cacheContainer="cacheContainer" /></div>
And DayJournalItem have another loop with other component ActivityJournalItem which has form
<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
<t:zone t:id="dayAjaxZone" update="show">
<div class="dayHeader">${dayHeader}</div> <div class="dayBody">
<div t:type="Loop" t:source="activities" t:value="activity"><t:ActivityJournalItem
activity="activity" cacheContainer="cacheContainer" /></div>
</div>
</t:zone></div>
ActivityJournalItem component
<div xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
<t:zone t:id="activityAjaxZone" update="show">
<t:if test="${editingActivity}">
<div class="activityEditFormBody">
<form t:type="form" t:id="activityForm" t:zone="activityAjaxZone">
....
<input t:id="Save" t:type="Submit" value="Save" />
<input t:id="Cancel" t:type="Submit" value="Cancel" />
</form>
</div>
</t:if>
<t:if test="${!editingActivity}">
<div>viewing activity: ${activity.id}</div>
</t:if>
</t:zone></div>
The problem is - when I'm pressing submit button NullPointerException appearing. All fields in my custom component are null. It seems that Tapestry is unable to restore context correctly. You can look at screenshoot here: http://my.jetscreenshot.com/2672/20100807-tbfe-235kb.jpg
I think I missing some parameters in form, loop or somewhere. And cant figure out what is wrong. By the way, I tried to use encoders, but Tapestry dont event call for them - it seems that they work only inside form. But I have form inside loop.
So any help is greatly appreciated.
p.s. If you need more details you can look at full source code (at google code): http://code.google.com/p/tasks-journal/source/checkout
UPD: I found that I can pass t:context to form and in onPrepareForSubmit phase I can restore fields manually (via pretty dirty work-around). Well, no NPE now, but: 1. This is ugly; 2. This is do not leads to form rerender. No Exceptions and no rerender as expected. I inspected HTTP response there is only empty brackets = "{}"
UPD2: I still playing with bad workaround. I figured out that if I in onSuccess will "return this;" then rerender will occur. But (!) it always rerender first form (or zone?) on the page. http://my.jetscreenshot.com/2672/20100808-thdx-190kb.jpg
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过
t:context
手动恢复组件的状态是正确的做法。仅当循环位于表单内部时,编码器才能为您提供帮助;就你而言,情况恰恰相反。我怀疑您正在渲染的区域在客户端都具有相同的 ID,因此第一个区域的内容被替换。您可能需要手动将 ID 分配给您的区域,如下所示:
Restoring the state manually of the component manually via
t:context
is the correct approach. Encoders can only help you if the loop is inside a form; in your case it is the other way around.I suspect the Zones you're rendering all have the same ID on the client side, hence the content of the first one is replaced. You may have to manually assign IDs to your Zones like this:
答案终于找到了。
将 id="something${counter}" 添加到区域 ActivityAjaxZone
通过此 id(html dom id)引用此区域Tapestry id
,它将起作用。
感谢乔什帮助回答:http://markmail.org/message/3lmnwybswwm7lhjm
Answere was finally found.
Add id="something${counter}" to the zone activityAjaxZone
Reference this zone by this id (html dom id) not tapestry id
And it will work.
Thank to Josh, who helped with answer: http://markmail.org/message/3lmnwybswwm7lhjm