2

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

故事是这样的:我有动态的形式,几乎没有工作模式。可以使用 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 - 似乎组件没有在我的表单类定义中初始化。另一方面,表单组件被正确注入(例如,我可以写一些错误)。我现在有点失落。如何正确地将我的组件注入到包含表单的类页面?

4

2 回答 2

1

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

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

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

于 2013-09-04T08:48:16.533 回答
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>

爪哇:

@Inject
private Block companyBlock, personalBlock, multiBlock;

public Block getMyBlock(){
    if (getShowCompany()) return companyBlock;
    if (getShowPersonal()) return personalBlock;
    return multiBlock;
}
于 2013-09-03T22:25:52.933 回答