2

我似乎无法让视图范围的托管 bean 与 setPropertyActionListener 一起工作:

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

如果 companyHolder 是会话或请求范围,则此方法可以正常工作,但如果其视图范围为无效。这是正常的吗?

4

1 回答 1

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>

<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>

于 2011-07-18T13:21:47.917 回答