我在为枚举对象属性预先选择HTML组合框的选项时遇到问题。这是我的代码的描述。我有一个公司模型类,其中包含CompanyPhone的列表:
@Entity
public class Company {
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
public List<CompanyPhone> phones;
...
}
CompanyPhone有一个PhoneType类型的phoneType属性,它是枚举:
@Column(name = "PHONE_TYPE")
public PhoneType type;
下面是带有静态options()方法的PhoneType枚举,用于获取用于在HTML模板中显示选择框选项的Map:
public enum PhoneType {
@EnumValue("MAI") MAIN,
@EnumValue("MOB") MOBILE,
@EnumValue("FAX") FAX,
@EnumValue("CUS") CUSTOM;
public static Map<String, String> options() {
LinkedHashMap<String, String> options = new LinkedHashMap<String, String>();
for (PhoneType v : PhoneType.values()) {
try {
EnumValue a = v.getClass().getField(v.name()).getAnnotation(EnumValue.class);
options.put(a.value(), Messages.get(String.format("%s.%s",
PhoneType.class.getSimpleName(), v.name())));
} catch (NoSuchFieldException | SecurityException e) { /* ignore */ }
}
return options;
}
}
基于Ebean文档,我选择使用@EnumValue注释来指定将存储在数据库中的值。我还实现了formatter来在PhoneType枚举和String之间进行转换,并在根包中的Global.java的onStart方法中注册它:
public class Global extends GlobalSettings {
@Override
public void onStart(Application app) {
Formatters.register(PhoneType.class, new PhoneTypeFormatter());
....
}
...
}
这是格式化程序类,仅供参考:
public class PhoneTypeFormatter extends SimpleFormatter<PhoneType> {
@Override
public PhoneType parse(String input, Locale locale) throws ParseException {
PhoneType phoneType = null;
for (PhoneType v : PhoneType.values()) {
try {
EnumValue a = v.getClass().getField(v.name()).getAnnotation(EnumValue.class);
if (input != null && a != null && input.equals(a.value())) {
phoneType = v;
break;
}
} catch (NoSuchFieldException | SecurityException e) { /* ignore */ }
}
return phoneType;
}
@Override
public String print(PhoneType phoneType, Locale locale) {
String v = null;
try {
v = (phoneType.getClass().getField(phoneType.name())
.getAnnotation(EnumValue.class)).value();
} catch (NoSuchFieldException | SecurityException e) { /* ignore */ }
return v;
}
}
现在,为了显示多个手机的输入字段,我在HTML模板文件中使用了Play2 @repeat指令。这是一个摘录:
...
@phoneGroup(field: Field, className: String = "companyPhone") = {
<div class="control-group @className">
<label class="control-label" for="@field("type").id">@Messages("company.phoneNumbers")</label>
<div class="controls">
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null && value == field("type").value) { selected }>@text</option>
}
</select>
<input type="text" class="inputAreaCode" id="@field("areaCode").id"
name="@field("areaCode").name" value="@field("areaCode").value"
placeholder="@Messages("phone.areaCode")">
<input type="text" class="input-medium" id="@field("number").id"
name="@field("number").name" value="@field("number").value"
placeholder="@Messages("phone.number")">
<a class="removePhone btn btn-danger">@Messages("button.remove")</a>
</div>
</div>
}
...
@main {
...
<div class="companyPhones well">
@repeat(companyForm("phones"), min = 1) { phone =>
@phoneGroup(phone)
}
@**
* Keep the hidden block that will be used as template for Javascript copy code.
**@
@phoneGroup(
companyForm("phones[x]"),
className = "companyPhone_template")
<div class="manage_repeat">
<a class="addPhone btn btn-success">@Messages("phone.add")</a>
</div>
</div>
...
}
到目前为止一切顺利。当我填写表格并提交数据时,电话号码正确存储在数据库中。但是,当我使用相同的表单编辑现有数据时,组合框中未选中当前的电话类型选项。似乎以下以红色突出显示的@if指令不起作用。但是没有显示错误:
@phoneGroup(field: Field, className: String = "companyPhone") = {
...
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null && value == field("type").value) { selected }>@text</option>
}
</select>
...
}
我尝试在选择前显示span元素中的@field(“type”)。值的值(以蓝色突出显示),HTML页面上的输出值是正确的,但是“FAX”的当前值未被选中:
@phoneGroup(field: Field, className: String = "companyPhone") = {
...
<span>Selected type: @field("type").value</span>
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null && value == field("type").value) { selected }>@text</option>
}
</select>
...
}
上面的模板输出以下HTML:
...
<span>Selected type: FAX</span>
<select id="phones_0__type" name="phones[0].type" class="input-small">
<option value="MAI">Main</option>
<option value="MOB">Mobile</option>
<option value="FAX">Fax</option>
<option value="CUS">Custom</option>
</select>
...
我被困在这里。我不熟悉Scala,模板的Scala文档对我来说不是很直观。我也尝试显示@field(“type”)。value的值而不是“selected”,只是为了好玩,就像那样:
@phoneGroup(field: Field, className: String = "companyPhone") = {
...
<span>Selected type: @field("type").value</span>
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null) { @field("type").value }>@text</option>
}
</select>
...
}
它输出正确的值但是小写:
...
<span>Selected type: FAX</span>
<select id="phones_0__type" name="phones[0].type" class="input-small">
<option value="MAI" fax>Main</option>
<option value="MOB" fax>Mobile</option>
<option value="FAX" fax>Fax</option>
<option value="CUS" fax>Custom</option>
</select>
...
这看起来很奇怪,在一个地方,它以大写字母输出,而另一个地方以小写字母输出。所以,在那之后,另一个尝试只是直接比较字符串值:
...
<span>Selected type: @field("type").value</span>
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null && "FAX".equals(field("type").value)) { selected }>@text</option>
}
</select>
这里仍然没有运气。在任何情况下,我仍然无法弄清楚如何获得所需的结果,以便在组合框中选择当前值(在这种情况下为“传真”)。您能否建议如何做到这一点,还是有其他替代方法?
感谢任何帮助。谢谢。
更新2013-11-06 - 找到适合我的解决方案:
好的人,在浏览了一下Play源代码树中的scala / views / helper文件后,我尝试了在inputRadioGroup.scala.html中找到的if语句
所以我在模板中更改了if语句,如下所示:
<select id="@field("type").id" name="@field("type").name" class="input-small">
@for((value, text) <- models.PhoneType.options) {
<option value="@value"
@if(field("type").value != null && Some(value) == (field("type").value)){ selected }>@text</option>
}
</select>
因此,使用 某些(值) 修复了问题,现在在组合框中选择了当前选项。我真的不明白这意味着什么,我可能需要学习一点Scala来更好地理解模板,但它有效。