【问题标题】:How to get data from tapestry textfield with the same name?如何从具有相同名称的挂毯文本字段中获取数据?
【发布时间】:2018-02-19 03:35:50
【问题描述】:

我对挂毯很陌生, 我在使用它时遇到了几个问题,如何从具有相同名称的挂毯文本字段中获取值?

例如:

<t:form t:id="names">
    <t:errors/>
    <div class="input-box">
        <t:textfield type="text" name="birthdate[Day]"/>
        <t:textfield type="text" name="birthdate[Month]"/>
        <t:textfield type="text"  name="birthdate[Year]"/>
    </div>
    <div class="input-box">
        <div class="col-md-12">
            <input type="submit" name="proceed" class="btn" value="Proceed" />
        </div>
    </div>
</t:form>

我尝试用birthdate[Day] = 20,birthdate[Month] = 08,birthdate[Year] = 1992 填充它,然后像这样在后端调试它:

@Property
@Persist(PersistenceConstants.FLASH)
private List<String> birthdate;

Object onSuccess() {
    logger.info("data birthdate:            "+birthdate);  // print null
    logger.info("data birthdate toString:   "+birthdate.toString());  // print null
    logger.info("data birthdate 0:          "+birthdate.get(0));  // print null

    return null;
}

他们都只返回null..

如何解决?

提前谢谢你

【问题讨论】:

  • 你为什么有一个 List 生日;而不是 3 个字段来捕获 3 个不同文本字段的值?或者你为什么不使用 DateField?
  • DateField 不可自定义,我的应用程序使用另一个 3rd 方日期选择器.. 和大约 3 个字段,我不能这样做,因为我的前端开发人员一直要求我构建这样的输入(3 输入 1 名称)...这是使用挂毯的弊端吗?
  • 当然你可以保持名称不变,但是你需要指定t:id,它用于将值从Names.tml映射到Names.java POJO。
  • 有一张地图.. &lt;t:textfield type="text" name="birthdate[Day]"/&gt;private List&lt;String&gt; birthdate;。看到这个:stackoverflow.com/a/42370754/2647910 看看评论我认为他也遇到了困难
  • 挂毯和弹簧混合在一起......我的回答中只使用了挂毯!

标签: java spring tapestry


【解决方案1】:

来自 Spring 和 Hibernate 时代,Tapestry 感觉很奇怪。根据我 10 分钟的阅读,您没有正确映射字段并且缺少一些内容,例如

  • 你没有使用t:id
  • .tml 中有 3 个文本字段,.java 中有一个列表,不确定您打算在那里做什么

作为一个例子,我做了如下Names.java

package com.raf.test.pages;

import java.util.Date;

import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.slf4j.Logger;

public class Names {
    @Inject
    private Logger logger;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private String birthDay;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private String birthMonth;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private String birthYear;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private String aDate;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private String monthAndYear;

    @Property
    @Persist(PersistenceConstants.FLASH)
    private Date actualDateField;

    Object onSuccess() {
       logger.info("birthDay: " + birthDay);
       logger.info("birthMonth: " + birthMonth);
       logger.info("birthYear: " + birthYear);

       if(aDate != null && !aDate.isEmpty()) {
           String[] chunks = aDate.split("-");
           if(chunks.length > 2) {
               logger.info("aDate [Year]: " + chunks[0]);
               logger.info("aDate [Month]: " + chunks[1]);
               logger.info("aDate [Day]: " + chunks[2]);
           }
       }

       logger.info("monthAndYear: " + monthAndYear);

       logger.info("actualDateField: " + actualDateField);

       return null;
    }
}

Names.tml如下

<html t:type="layout" title="test com.example"
      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
      xmlns:p="tapestry:parameter">

<t:form t:id="names">
    <t:errors/>
    <div class="input-box">
        <t:textfield type="text" name="birthdate[Day]" placeholder="birthdate[Day]" t:id="birthDay"/>
        <t:textfield type="text" name="birthdate[Month]" placeholder="birthdate[Month]" t:id="birthMonth"/>
        <t:textfield type="text"  name="birthdate[Year]" placeholder="birthdate[Year]" t:id="birthYear"/>
        <!-- Uses html5 date type-->
        <t:textfield type="date"  name="normladate" placeholder="Normal date" t:id="aDate"/>

        <!-- Uses html5 month -->
        <t:textfield type="month"  name="justmonth" placeholder="Month Year" t:id="monthAndYear"/>

        <!-- Actual date field -->
        <t:datefield  name="actualDateField" placeholder="Actual date" t:id="actualDateField"/>
    </div>
    <div class="input-box">
        <div class="col-md-12">
            <input type="submit" name="proceed" class="btn" value="Proceed" />
        </div>
    </div>
</t:form>
</html>

这是 eclipse 中的示例输出

[INFO] pages.Names birthDay: bb
[INFO] pages.Names birthMonth: aa
[INFO] pages.Names birthYear: 2nineteen
[INFO] pages.Names aDate [Year]: 2018
[INFO] pages.Names aDate [Month]: 02
[INFO] pages.Names aDate [Day]: 18
[INFO] pages.Names monthAndYear: 2018-02
[INFO] pages.Names actualDateField: Fri Feb 16 00:00:00 EST 2018

如您所见,Names.tml 中的每个字段都映射到Names.java POJO 中的相应字段。

【讨论】:

  • You are not using t:id 我不知道..但是添加 t:id 在这里不起作用.. 仍然为空.. You have 3 text fields in your .tml and then a list in your .java 我想该列表可以捕获具有相同名称的输入..
【解决方案2】:

您似乎认为Tapestry 的TextField 与HTML“input type=text”HTML 元素相同。它不是。 TextField 是一个 Tapestry 组件,输出一个“input type=text”HTML 元素,但它使用“value”参数而不是“name”来标识正在编辑的对象,如文档中所述:@ 987654321@

我提供了 3 种可能的方法:

1) 如果可能,不要使用 3 元素列表作为日期部分。那只会让一切变得更加困难和混乱。相反,每个属性都有一个单独的属性,称为birthDay、birthMonth 和birthYear:

@Property
@Persist(PersistenceConstants.FLASH)
private String birthDay, birthMonth, birthYear;

在您的模板中包含以下内容:

<t:textfield t:id="birthDay" value="birthDay"/>
<t:textfield t:id="birthMonth" value="birthMonth"/>
<t:textfield t:id="birthYear" value="birthYear"/>

或在您的模板中使用以下内容,这是等效的(因为 Tapestry 使用查找与 t:id 参数匹配的属性,如果它没有找到值参数)并且更简洁:

<t:textfield t:id="birthDay"/>
<t:textfield t:id="birthMonth"/>
<t:textfield t:id="birthYear"/>

2) 或者,如果您真的想通过为每个字段使用相同的“名称”属性来让您的网页设计师满意,您可以这样写,等效地:

<input type="text" t:type="textfield t:id="birthDay" name="birthday"/>
<input type="text" t:type="textfield t:id="birthMonth" name="birthday"/>
<input type="text" t:type="textfield t:id="birthYear" name="birthday"/>

(如果您确实在 Tapestry 组件上添加了“名称”参数,那么它的值将被忽略,并且 不会 出现在生成的 HTML 中。相反,TextField 发出的 HTML(通常)包括一个 name 属性,其值与 t:id 属性匹配。)

3) 最后,您可以完全跳过 TextField 组件,而只使用带有 3 元素字符串列表的普通旧 HTML 表单元素:

<input type="text" name="birthday" value="${birthdate.get(0)}"/>
<input type="text" name="birthday" value="${birthdate.get(1)}"/>
<input type="text" name="birthday" value="${birthdate.get(2)}"/>

然后您可以使用以下方法检索提交的值:

@Inject
private Request request;
...
String[] birthDateParts = request.getParameters("birthday");
birthdate = Arrays.asList(birthDateParts);

这很尴尬。而且您失去了 Tapestry 的所有有用的验证和错误报告功能,您必须自己管理所有细节。所以我不推荐这条路线。

【讨论】:

  • &lt;t:textfield t:id="birthDay" value="birthdate[Day]"/&gt; 这个世界怎么样?是的,我对挂毯很陌生..我明天早上会试试那个代码..
  • 你说得对,birthdate[Day] 语法不起作用。我不小心从你的问题中复制了这一点。我已经重写了我的答案。如果现在更有意义,请告诉我。
猜你喜欢
  • 2014-05-05
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多