Tapestry 5自定义组件形式 - 验证期间访问

时间:2013-09-03 21:07:30

标签: forms dependency-injection custom-component tapestry

A访问我的自定义组件(用作表单的一部分)时遇到问题。

以下是故事: 我有动态形式,几乎没有工作方式。可以选择每种模式并使用AJAX加载到表单体中。它看起来像(模板):

<t:form t:id = "form">
    <p class= "calcModeTitle">
        ${message:modeLabel}: <select t:id="modeSelect"
                  t:type="select" 
                  t:model="modesModel" 
                  t:value="selectedMode"  
                  t:blankOption="NEVER" 
                  t:encoder="modeEncoder"
                  t:zone = "modeZone"
        />
    </p>

    <div class="horizontal_tab">
        <t:errors/>
    </div>

    <t:zone t:id="modeZone" id="modeZone" t:update="show">
        <t:if test="showCompany">
            <t:delegate to="block:companyBlock" />
        </t:if>
        <t:if test="showPersonal">
            <t:delegate to="block:personalBlock" />
        </t:if>
        <t:if test="showMulti">
            <t:delegate to="block:multiBlock" />
        </t:if>
    </t:zone>

    <t:block id="companyBlock">
         <t:modes.CompanyMode t:id="company"/>
    </t:block>

    <t:block id="personalBlock">
        <t:modes.PersonalMode t:id="personal" />
    </t:block>

    <t:block id="multiBlock">
        <t:modes.MultiMode t:id="multi" />
    </t:block>

    <div class="horizontal_tab">
        <input type="submit" value="${message:submit_label}" class="submitButton thickBtn"/>
    </div>

</t:form>

AJAX运行良好,并相应地形成“modeSelect”状态的变化。但是在提交表单时我遇到了问题。我在组件的类定义钩子中放置了:

//----form elements
@Component(id = "form")
private Form form;

@InjectComponent
private CompanyMode company;

@InjectComponent
private PersonalMode personal;

@InjectComponent
private MultiMode multi;

其中* Mode类是我自己的组件,包含表单元素和输入组件。我计划在验证期间访问它们,并检查用户使用表单提供的值,但是当我尝试从它们获取任何内容时,我有nullPointerException - 似乎组件未在我的类形式定义中初始化。另一方面,表单组件被正确注入(例如,我能够写一些错误)。我现在有点迷失了。如何正确地将我的组件注入包含表单的类页面?

2 个答案:

答案 0 :(得分:1)

挂毯中的动态表单有点复杂。 Tapestry传递t:formdata请求参数,该参数包含序列化表单实体。然后在POST中使用服务器端来重新补充初始形式状态。这必须与客户看到的内容保持同步。

如果您想通过ajax向表单添加动态内容,则需要使用FormInjector。您可能需要查看AjaxFormLoop的源代码以查看示例。

如果要渲染隐藏的表单片段并根据客户端逻辑使其可见,可以使用FormFragment

答案 1 :(得分:0)

来自挂毯指南:

  

通常不会渲染块;您放置的任何组件或内容   通常不会渲染块内。但是,通过注射   块你可以精确控制内容的时间和内容   渲染。

尝试在这里使用“t:if”或“t:delegate”。

这样的事情:

<t:zone t:id="modeZone" id="modeZone" t:update="show">
      <t:delegate to="myBlock" /> 
</t:zone>

<t:block t:id="companyBlock">
     <t:modes.CompanyMode t:id="company"/>
</t:block>
<t:block t:id="personalBlock">
    <t:modes.PersonalMode t:id="personal" />
</t:block>

<t:block t:id="multiBlock">
    <t:modes.MultiMode t:id="multi" />
</t:block>

的java:

@Inject
private Block companyBlock, personalBlock, multiBlock;

public Block getMyBlock(){
    if (getShowCompany()) return companyBlock;
    if (getShowPersonal()) return personalBlock;
    return multiBlock;
}