创建新视图时会创建一个全新的视图范围 bean。目标视图保存的视图范围 bean 的实例与由表单的初始视图上的操作方法设置属性的位置不同。
乍一看确实不直观,但这就是视图范围的工作方式。视图范围 bean 的存在时间与视图存在的时间一样长。毕竟这是有道理的。
你最好的选择是使用<f:param>
而不是<f:setPropertyActionListener>
让目标视图设置它<f:viewParam>
。
例如
<h:commandButton value="Edit" action="edit-company.xhtml">
<f:param name="companyId" value="#{company.id}"/>
</h:commandButton>
和
<f:metadata>
<f:viewParam name="companyId" value="#{bean.company}" required="true" />
</f:metadata>
和
@ManagedBean
@ViewScoped
public class Bean {
private Company company;
// ...
}
和
@FacesConverter(forClass=Company.class)
public class CompanyConverter implements Converter {
@Override
public void getAsObject(FacesContext context, UIComponent component, Object value) throws ConverterException {
try {
return companyService.find(Long.valueOf(value));
} catch (Exception e) {
throw new ConverterException(new FacesMessage(
String.format("Cannot convert %s to Company", value)), e);
}
}
// ...
}
void
作为一个完全不同的替代方案,您也可以通过返回或null
有条件地呈现包含来导航回相同的视图。
<ui:include src="#{bean.editmode ? 'edit' : 'view'}.xhtml" />
但是,如果您需要支持 GET 而不是 POST(顺便说一下,您需要替换它<h:commandButton>
) ,这将不起作用<h:button>
。