Forms Tapestry 5表单中的自定义组件-验证期间的访问

Forms Tapestry 5表单中的自定义组件-验证期间的访问,forms,dependency-injection,custom-component,tapestry,Forms,Dependency Injection,Custom Component,Tapestry,A在访问自定义组件(用作表单的一部分)时遇到问题 故事是这样的: 我有一个动态的形式,它几乎没有工作模式。每个模式都可以通过AJAX选择并加载到表单体中。它看起来像(模板): 其中*模式类是我自己的组件,包含表单元素和输入组件。我计划在验证期间访问它们,并检查用户随表单提供的值,但当我试图从中获取任何内容时,我得到了nullPointerException—组件似乎未在表单的类定义中初始化。另一方面,表单组件被正确地注入(例如,我能够编写一些错误)。我现在有点迷路了。如何正确地将我的组件注入包含

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

故事是这样的: 我有一个动态的形式,它几乎没有工作模式。每个模式都可以通过AJAX选择并加载到表单体中。它看起来像(模板):

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

来自tapestry指南:

块通常不会渲染;您放置的任何组件或内容 通常不会渲染块内部。然而,通过注射 您可以精确控制内容何时和是否被删除的块 渲染

尝试在此处使用“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>

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

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


如果您想要呈现隐藏的表单片段,并基于客户端逻辑使其可见,您可以使用

技术上这只是我在代码中使用的另一种方法。问题是我用AJAX更改表单的内容,这在Tapestry中似乎是不允许的(至少不仅仅是通过切换块)。感谢您的提示,带有一些服务器端条件的FormFragment完成了它的工作。看起来,只要我没有弄乱表单的结构,用AJAX重新加载表单是可以的。幸运的是,我不需要向表单中注入任何内容,我可以一次放入所有内容,并通过前面提到的FormFragment控制可见性。再次感谢,您已经保存了我的一天(甚至是其中的两天。)是的,重新加载整个表单很好,因为您将在新表单中获得一个新的
t:formdata
值。尝试查看HTML源代码,你会看到它。好吧,我甚至成功地用AJAX重新加载了它的一部分,但我仍然保持了相同的结构。无论如何,我得到了我所需要的,并且或多或少地理解了为什么它现在能工作,为什么以前不能。谢谢。这可能很危险,具体取决于你在做什么
t:formdata
是tapestry了解用于呈现表单的实体的方式。如果你不及时更新。。。例如,tapestry可能会更新错误的实体。
//----form elements
@Component(id = "form")
private Form form;

@InjectComponent
private CompanyMode company;

@InjectComponent
private PersonalMode personal;

@InjectComponent
private MultiMode multi;
<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;
}