在仪表板上,每个用户都可以看到一些基本统计信息。让我们以“最后登录”日期为例。 (但还有更多的统计数据/值/设置要显示)
XHTML文件看起来像这样简单:
<h:outputText value="statisticController.lastLoginDate()" />
Bean本身使用@Inject
来获取Session,因此使用当前用户:
@Named
@RequestScoped
public StatisticController{
@Inject
private mySessionBean mySession;
@PostConstruct
private void init(){
//load stats for mySession.currentUser;
}
}
现在,我想生成一个List,例如某个角色可以查看所有用户的值。因此我不能再使用Session Inject,因为现在需要为多个用户生成StatisticController。
使用常规类这不会是一个大问题 - 将userEntity添加到构造函数中。在JSF中解决这个问题的“最佳实践”是什么?
如果我将StatisticController修改为这样的东西:
@Named
@RequestScoped
public StatisticController{
public void init(User user){
//load stats for user;
}
}
我当然需要手动拨打init(user)
。如何在XHTML文件的迭代中实现?
我可以重构它,以便在实际的getter方法中发生valueLoading,并像这样迭代:
<ui:repeat var="user" value="#{userDataService.getAllUsers()}">
<h:outputText value="statisticController.lastLoginDate(user)" />
...
</ui:repeat>
但是我需要加载“每个”值分开,这很糟糕。
所以这样的方式会“更好”:
<ui:repeat var="user" value="#{userDataService.getAllUsers()}">
statisticController.init(user);
<h:outputText value="statisticController.lastLoginDate()" />
...
</ui:repeat>
然而,这看起来也不舒服。进一步做这样的事情,将几乎“全部”后端东西移动到渲染响应阶段,这是错误的。
任何Ideas / Tipps如何以一种不像“变形方式”的方式解决这个问题?
答案 0 :(得分:2)
创建一个包装这些模型的新模型。
public class UserStatistics {
private User user;
private Statistics statistics;
// ...
}
这样你就可以使用例如。
public class UserStatisticsBacking {
private List<UserStatistics> list;
@EJB
private UserService userService;
@EJB
private StatisticsService statisticsService;
@PostConstruct
public void init() {
list = new ArrayList<UserStatistics>();
for (User user : userService.list()) {
list.add(new UserStatistics(user, statisticsService.get(user)));
}
}
// ...
}
(更好的方法是在新的UserStatisticsService
执行
与
<ui:repeat value="#{userStatisticsBacking.list}" var="userStatistics">
<h:outputText value="#{userStatistics.user.name}" />
<h:outputText value="#{userStatistics.statistics.lastLoginDate}" />
...
</ui:repeat>
答案 1 :(得分:0)
使用BalusC提出的包装模型的另一种方法是使用模型数据存储两个单独的列表。使用这种方法,您无需进行修改。
遵循此路线,您将使用<ui:repeat>
迭代一个列表,并确保两个列表的大小相等,按索引获取第二个列表元素,而这又可通过varStatus
属性获得导出迭代状态变量。
<ui:param name="stats" value="#{bean.stats}/>
<ui:repeat value="#{bean.users}" var="user" varStatus="status">
<h:outputText value="#{user}/>
<h:outputText value="#{stats[status.index]}/>
</ui:include>
列表的人口可以事先用PostConstruct
方法完成:
private List<User> users;
private List<Statistic> stats;
@PostConstruct
public void init() {
users = userService.list();
stats = statService.list();
}