使用setPropertyActionListener查看作用域托管bean

DD.*_*DD. 2 scope jsf-2 managed-bean

我似乎无法使视图作用域托管bean与setPropertyActionListener一起使用:

   <h:commandButton value="Edit"  action="edit-company.xhtml">
    <f:setPropertyActionListener target="#{companyHolder.item}" value="#{company}"/>            
   </h:commandButton>
Run Code Online (Sandbox Code Playgroud)

如果companyHolder是会话或请求作用域,但如果其视图作用域,则无效.这是正常的吗?

Bal*_*usC 6

创建新视图时,会创建一个全新的视图范围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>
Run Code Online (Sandbox Code Playgroud)

<f:metadata>
    <f:viewParam name="companyId" value="#{bean.company}" required="true" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)

@ManagedBean
@ViewScoped
public class Bean {

    private Company company;

    // ...
}
Run Code Online (Sandbox Code Playgroud)

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

作为一个完全不同的替代方案,您还可以通过返回voidnull有条件地渲染包含来导航回相同的视图.

<ui:include src="#{bean.editmode ? 'edit' : 'view'}.xhtml" />
Run Code Online (Sandbox Code Playgroud)

然而,这如果需要支持GET而不是POST(您将需要更换不工作<h:commandButton><h:button>方式).