1

我有以下情况:我有在某些上下文中激活的页面(例如“/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 如果您需要更多详细信息,可以查看完整的源代码(在 google 代码中):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

4

2 回答 2

1

通过手动恢复组件的状态t:context是正确的方法。编码器只能在循环位于表单内时为您提供帮助;在你的情况下,情况正好相反。

我怀疑您正在渲染的区域在客户端都具有相同的 ID,因此第一个区域的内容被替换。您可能必须手动将 ID 分配给您的区域,如下所示:

<t:zone t:id="dayAjaxZone" id="dayAjaxZone${dayIndex}" update="show">
于 2010-08-09T08:45:06.927 回答
0

终于找到了答案。

  1. 将 id="something${counter}" 添加到区域 activityAjaxZone

  2. 通过这个 id(html dom id)而不是挂毯 id 引用这个区域

它会起作用。

感谢 Josh,他帮助回答: http: //markmail.org/message/3lmnwybswwm7lhjm

于 2010-08-13T02:57:25.893 回答