如何从具有相同名称的挂毯文本字段中获取数据?
How to get data from tapestry textfield with the same name?
我对挂毯很陌生,
我在使用它时遇到了几个问题,如何从同名的挂毯文本字段中获取值?
例如:
<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>
我尝试用生日[日] = 20、生日[月] = 08、生日[年] = 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..
如何解决?
提前致谢
来自 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 中的相应字段。
您似乎认为 Tapestry 的 TextField 是 与 HTML "input type=text" HTML 元素相同的东西。它不是。 TextField 是一个 Tapestry 组件,它 输出 一个 "input type=text" HTML 元素,但它使用 "value" 参数而不是 [=48] 标识正在编辑的对象=],如文档中所述:http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextField.html
我提供了 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) 或者,如果您真的想让您的网页设计师对每个字段使用相同的 "name" 属性,那么您可以这样写,等价于:
<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 组件上添加了 "name" 参数,那么它的值将被忽略并且 而不是 出现在结果 HTML 中。相反,TextField 发出的 HTML(通常)包含一个名称属性,其值与 t:id 属性匹配。)
3) 最后,您 可以 完全跳过 TextField 组件,只使用普通的旧 HTML 表单元素和您的 3 元素字符串列表:
<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 的所有有用的验证和错误报告功能,并且您必须自己管理所有细节。所以我不推荐这条路线。
我对挂毯很陌生, 我在使用它时遇到了几个问题,如何从同名的挂毯文本字段中获取值?
例如:
<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>
我尝试用生日[日] = 20、生日[月] = 08、生日[年] = 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..
如何解决?
提前致谢
来自 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 中的相应字段。
您似乎认为 Tapestry 的 TextField 是 与 HTML "input type=text" HTML 元素相同的东西。它不是。 TextField 是一个 Tapestry 组件,它 输出 一个 "input type=text" HTML 元素,但它使用 "value" 参数而不是 [=48] 标识正在编辑的对象=],如文档中所述:http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextField.html
我提供了 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) 或者,如果您真的想让您的网页设计师对每个字段使用相同的 "name" 属性,那么您可以这样写,等价于:
<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 组件上添加了 "name" 参数,那么它的值将被忽略并且 而不是 出现在结果 HTML 中。相反,TextField 发出的 HTML(通常)包含一个名称属性,其值与 t:id 属性匹配。)
3) 最后,您 可以 完全跳过 TextField 组件,只使用普通的旧 HTML 表单元素和您的 3 元素字符串列表:
<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 的所有有用的验证和错误报告功能,并且您必须自己管理所有细节。所以我不推荐这条路线。