使用setPropertyActionListener查看作用域托管bean

时间:2011-07-18 12:01:18

标签: jsf-2 scope managed-bean

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

   <h:commandButton value="Edit"  action="edit-company.xhtml">
    <f:setPropertyActionListener target="#{companyHolder.item}" value="#{company}"/>            
   </h:commandButton>

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

1 个答案:

答案 0 :(得分:6)

创建新视图时,会创建一个全新的视图范围bean。目标视图包含视图范围bean的不同实例,而不是使用表单的初始视图上的操作方法设置属性的位置。

乍一看确实不直观,但这就是视图范围的工作原理。只要视图存在,视图范围的bean就会存在。毕竟这很有意义。

您最好的选择是使用<f:param>代替<f:setPropertyActionListener>,并让目标视图按<f:viewParam>设置。

E.g。

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

    // ...
}

作为完全不同的替代方案,您还可以返回voidnull并有条件地渲染包含,然后导航回同一视图。

<ui:include src="#{bean.editmode ? 'edit' : 'view'}.xhtml" />

但是,如果您需要支持GET而不是POST(根据<h:commandButton>,您需要替换<h:button>),这不起作用。