2

我有一个如下的支持bean:

@Named
@RequestScoped
public class ClientNewBackingBean {

    @Inject
    private ClientFacade facade;
    private Client client;

该类Client具有一个List<Child> childrenList属性,等等。Client设置childrenListwith时,我可以创建一个新的new ArrayList()

在视图中,我有一个输入文本字段和一个Add Child按钮。该按钮的属性actionListener=#{clientNewBackingBean.addChild()}实现为:

public void addChild() {

    if(client.getChildrenList() == null) {
        client.getChildrenList(new ArrayList());
    }

    Child c = new Child("John Doe");

    client.getChildrenList().add(c);
}

每次Add Child单击按钮时,都会重新创建 bean,并且视图只显示一个 John Doe 孩子(我相信,由于它是 Request 范围的)。除了将bean范围更改为Session之外,还有其他方法可以解决这个问题吗?

4

2 回答 2

9

如果您使用标准的 JSF bean 管理注释@ManagedBean,您可以通过将 bean 放在视图范围中来解决它@ViewScoped

@ManagedBean
@ViewScoped
public class ClientNewBackingBean implements Serializable {

    @EJB
    private ClientFacade facade;

    // ...

然而,在 CDI@ViewScoped中不存在,最接近的替代方案是@ConversationScoped. 您只需要自己启动和停止它。

@Named
@ConversationScoped
public class ClientNewBackingBean implements Serializable {

    @Inject
    private Conversation conversation;

    // ...

    @PostConstruct
    public void init() {
        conversation.begin();
    }

    public String submitAndNavigate() {
        // ...

        conversation.end();
        return "someOtherPage?faces-redirect=true";
    }

}

您还可以使用 CDI 扩展MyFaces CODI,它将透明地桥接 JSF@ViewScoped注释,以便与@Named

@Named
@ViewScoped
public class ClientNewBackingBean implements Serializable {

    @Inject
    private ClientFacade facade;

    // ...

CODI 替代方案是使用@ViewAccessScoped它,只要后续请求引用相同的托管 bean,就可以使用它,而与使用的物理视图文件无关。

@Named
@ViewAccessScoped
public class ClientNewBackingBean implements Serializable {

    @Inject
    private ClientFacade facade;

    // ...

也可以看看:

于 2013-01-04T14:27:07.770 回答
0

如果您使用的是 JSF 2,则应该使用ViewScopedbean。

于 2013-01-04T14:25:02.587 回答