0

在仪表板上,每个用户都可以看到一些基本统计信息。让我们以“上次登录”日期为例。(但还有更多的统计数据/值/设置要显示)

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;
    }
}

现在,我想生成一个列表,例如某个角色可以查看所有用户的值。因此我不能再使用会话注入,因为现在需要为多个用户生成 StatisticController。

拥有常规类这不会是一个大问题 - 将 userEntity 添加到构造函数中。在 JSF 中解决这个问题的“最佳实践”是什么?

如果我将 StatisticController 修改为如下所示:

@Named
@RequestScoped
public StatisticController{

    public void init(User user){
       //load stats for user;
    }
}

我当然需要init(user)手动调用。如何在 XHTML 文件的迭代中实现这一点?

我可以重构它,以便 valueLoading 发生在实际的 getter 方法中,并像这样迭代:

<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>

然而,这看起来也不是很舒服。进一步做这样的事情,会将几乎“所有”后端东西移到渲染响应阶段,这感觉不对。

任何想法/提示如何以一种不像“解决方法”的方式解决这个问题?

4

2 回答 2

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>
于 2013-04-10T12:22:04.033 回答
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();
}
于 2013-04-10T17:03:52.603 回答