我有一个支持bean如下:
@Named
@RequestScoped
public class ClientNewBackingBean {
@Inject
private ClientFacade facade;
private Client client;
Client
类具有List<Child> childrenList
属性等。使用Client
设置childrenList
时,我可以创建新的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 stroped,我相信)。除了将bean范围更改为Session之外,还有其他方法可以解决这个问题吗?
答案 0 :(得分:9)
如果您使用的是标准的JSF bean管理批注@ManagedBean
,那么您可以通过@ViewScoped
将bean放在视图范围内来解决它。
@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;
// ...
,无论使用何种物理视图文件。
{{1}}
答案 1 :(得分:0)
如果您使用的是JSF 2,则应使用ViewScoped
bean。