Jsf 将项目添加到请求范围Bean中的列表

Jsf 将项目添加到请求范围Bean中的列表,jsf,scope,cdi,Jsf,Scope,Cdi,我有一个支持bean,如下所示: @Named @RequestScoped public class ClientNewBackingBean { @Inject private ClientFacade facade; private Client client; Client类有一个List childrenList属性。使用new ArrayList()设置childrenList时,我可以创建一个新的客户端 在视图中,我有一个输入文本字段和一个addchil

我有一个支持bean,如下所示:

@Named
@RequestScoped
public class ClientNewBackingBean {

    @Inject
    private ClientFacade facade;
    private Client client;
Client
类有一个
List childrenList
属性。使用
new ArrayList()
设置
childrenList
时,我可以创建一个新的
客户端

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

public void addChild() {

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

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

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

每次单击
addchild
按钮时,bean就会被重新创建,并且视图只显示一个johndoe Child(我相信这是因为它是请求范围)。除了将bean范围更改为Session之外,还有其他解决方法吗

如果您使用的是JSF2,您应该使用
ViewScoped
bean。

如果您使用的是标准的JSFbean管理注释
@ManagedBean
,您可以通过将bean放置在视图范围中来解决这个问题

在CDI中,
@ViewScoped
但是不存在,最接近的替代方案是。你只需要自己开始和停止

@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扩展,它将透明地桥接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;

    // ...
另见:

改为MyFaces CODI方法,效果良好。MyFaces CODI将
@ViewScoped
连接到CDI。因此,您不必使用不同的注释
@ViewAccessScoped
是一个行为完全不同的作用域。CODI示波器在99%的范围内是更好的选择!只是JSF标准注释,是的。#1我不是CODI开发人员之一(只是一个“超级用户”)#2这是
@ViewScoped
(定义在JSF规范中)的正确行为。#3 IMHO
@ViewScoped
只对一些非常罕见的情况有用
@ViewAccessScope
执行您期望的操作
@ViewScope
由JSF规范指定,并绑定到一个视图。您不能在不同的页面上使用存储的值->如果您有一个页面,并且对同一页面有很多AJAX请求,并且您不需要在下一个页面上使用这些值,那么您应该使用它
@viewAccessScope
是CODI发明的自定义CDI范围。您的bean存在于下一个逻辑(不是HTTP-如果触发nav.with重定向,可能是2个HTTP请求)请求中,只要它们在逻辑请求期间被触及。如果需要,您还可以提前(手动)销毁它们。
@Named
@ViewAccessScoped
public class ClientNewBackingBean implements Serializable {

    @Inject
    private ClientFacade facade;

    // ...