将某个 class 的集合的布尔属性绑定到复选框
Binding boolean properties of a Set of a certain class to checkboxes
我希望(从我的数据库中)获取每个大陆的国家/地区列表作为带有复选框的标签,使特定国家/地区成为 shown/used 在我的网络应用程序中。
这是它的视觉效果。
因此我使用 Continent
class:
@Entity
public class Continent implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
@OneToMany(mappedBy = "continent")
private Set<Country> countries;
// Getters, equals, hashCode...
}
还有 Country
class:
@Entity
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "continentid")
private Continent continent;
private boolean enabled; // THE CHECKBOX
// Getters, equals, hashCode...
}
然后我在适当的控制器中为 Continent
初始化一个活页夹,并将请求的大陆(使用干净的 URL 作为参数)作为对象添加到我的 ModelAndView
(GET) :
@Controller
@RequestMapping("/continent")
public class LocaleController {
private final LocaleService localeService;
@Autowired
LocaleController(LocaleService localeService) {
this.localeService = localeService;
}
@InitBinder("continent")
void initBinderContinent(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
@RequestMapping(path="{continent}", method = RequestMethod.GET)
ModelAndView readContinent(@PathVariable Continent continent) {
return new ModelAndView("continent",
"continent", continent);
}
@RequestMapping(path="{continent}", method = RequestMethod.POST)
String editContinent(@PathVariable Continent continent) {
//TODO hasErrors etc.
localeService.updateContinent(continent);
return "redirect:/continents";
}
}
在我的 JSP 文件的 body
中,我编写了(将 taglib 用于 Spring 表单和 JSTL 核心):
<form:form commandName='continent' id='continentform'>
</form:form>
<h1>${continent.name}</h1>
<!-- SelectAll and UnselectAll buttons, other HTML tags -->
<c:forEach var="country" items="${continent.countries}" varStatus="loop">
<form:checkbox path="countries['${loop.index}'].enabled"/>
<form:label path="countries['${loop.index}'].enabled">
${country.name}
</form:label>
</c:forEach>
但这行不通:
首先:循环中的loop.index
不对应当前country
的Set<Country> countries
索引;我知道是因为 country.name
不等于 countries['${loop.index}'].name
其次: 标签 for=
属性与相应的复选框属性不对应 id=
.
ThirdlocaleService.updateContinent(continent)
调用continentDAO.save(continent)
(ContinentDAO
是扩展JpaRepository<Continent, Long>
的接口)但不更新启用状态国家。
我的错误是什么?
为了解决 第一个问题,我不再 return Continent
class 中的 Set<Country> countries
TreeSet (我只是returncountries
)。
为了解决第二个问题我编辑了我的JSP<c:forEach>
内容:
<c:forEach var="country" items="${continent.countries}" varStatus="loop">
<form:checkbox path="countries['${loop.index}'].enabled" cssClass="medium"
label="${country.name}"/>
</c:forEach>
为了解决第三个问题,我在 LocaleController
中编辑了 editContinent
函数,现在可以使用了:
@RequestMapping(path="{continent}", method = RequestMethod.POST)
String editContinent(@Valid Continent continent, BindingResult bindingResult) {
//TODO hasErrors etc.
localeService.updateContinent(continent);
return "redirect:/continents";
}
感谢 M. Deinum 非常有用的评论。
我希望(从我的数据库中)获取每个大陆的国家/地区列表作为带有复选框的标签,使特定国家/地区成为 shown/used 在我的网络应用程序中。
这是它的视觉效果。
因此我使用 Continent
class:
@Entity
public class Continent implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
@OneToMany(mappedBy = "continent")
private Set<Country> countries;
// Getters, equals, hashCode...
}
还有 Country
class:
@Entity
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "continentid")
private Continent continent;
private boolean enabled; // THE CHECKBOX
// Getters, equals, hashCode...
}
然后我在适当的控制器中为 Continent
初始化一个活页夹,并将请求的大陆(使用干净的 URL 作为参数)作为对象添加到我的 ModelAndView
(GET) :
@Controller
@RequestMapping("/continent")
public class LocaleController {
private final LocaleService localeService;
@Autowired
LocaleController(LocaleService localeService) {
this.localeService = localeService;
}
@InitBinder("continent")
void initBinderContinent(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
@RequestMapping(path="{continent}", method = RequestMethod.GET)
ModelAndView readContinent(@PathVariable Continent continent) {
return new ModelAndView("continent",
"continent", continent);
}
@RequestMapping(path="{continent}", method = RequestMethod.POST)
String editContinent(@PathVariable Continent continent) {
//TODO hasErrors etc.
localeService.updateContinent(continent);
return "redirect:/continents";
}
}
在我的 JSP 文件的 body
中,我编写了(将 taglib 用于 Spring 表单和 JSTL 核心):
<form:form commandName='continent' id='continentform'>
</form:form>
<h1>${continent.name}</h1>
<!-- SelectAll and UnselectAll buttons, other HTML tags -->
<c:forEach var="country" items="${continent.countries}" varStatus="loop">
<form:checkbox path="countries['${loop.index}'].enabled"/>
<form:label path="countries['${loop.index}'].enabled">
${country.name}
</form:label>
</c:forEach>
但这行不通:
首先:循环中的loop.index
不对应当前country
的Set<Country> countries
索引;我知道是因为 country.name
不等于 countries['${loop.index}'].name
其次: 标签 for=
属性与相应的复选框属性不对应 id=
.
ThirdlocaleService.updateContinent(continent)
调用continentDAO.save(continent)
(ContinentDAO
是扩展JpaRepository<Continent, Long>
的接口)但不更新启用状态国家。
我的错误是什么?
为了解决 第一个问题,我不再 return Continent
class 中的 Set<Country> countries
TreeSet (我只是returncountries
)。
为了解决第二个问题我编辑了我的JSP<c:forEach>
内容:
<c:forEach var="country" items="${continent.countries}" varStatus="loop">
<form:checkbox path="countries['${loop.index}'].enabled" cssClass="medium"
label="${country.name}"/>
</c:forEach>
为了解决第三个问题,我在 LocaleController
中编辑了 editContinent
函数,现在可以使用了:
@RequestMapping(path="{continent}", method = RequestMethod.POST)
String editContinent(@Valid Continent continent, BindingResult bindingResult) {
//TODO hasErrors etc.
localeService.updateContinent(continent);
return "redirect:/continents";
}
感谢 M. Deinum 非常有用的评论。