问题描述
我似乎无法使视图范围的托管bean与setPropertyActionListener一起使用:
I cant seem to get the view scoped managed bean to work with setPropertyActionListener:
<h:commandButton value="Edit" action="edit-company.xhtml">
<f:setPropertyActionListener target="#{companyHolder.item}" value="#{company}"/>
</h:commandButton>
如果companyHolder为会话或请求范围,则此方法正常,但如果其view为范围,则该方法不起作用.这正常吗?
This works fine if companyHolder is session or request scoped but doesnt work if its view scoped. Is this normal?
推荐答案
创建新视图时,将创建一个全新的视图作用域bean.目标视图与视图作用域bean的实例不同,该实例与通过action方法在具有表单的初始视图上设置属性的位置不同.
A brand new view scoped bean is been created when a new view is created. The target view holds a different instance of the view scoped bean than where the property is been set by the action method on the initial view with the form.
乍一看,这确实不直观,但这就是视图作用域的工作方式.一个视图范围的bean只要它存在就可以生存.毕竟是有道理的.
This is at first sight indeed unintuitive, but that's how the view scope works. A view scoped bean lives as long as the view lives. It makes sense after all.
您最好的选择是使用<f:param>
而不是<f:setPropertyActionListener>
,并让目标视图通过<f:viewParam>
进行设置.
Your best bet is using <f:param>
instead of <f:setPropertyActionListener>
and let the target view set it by <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
并导航到相同的视图,并有条件地呈现包含内容.
As a completely different alternative, you can also just navigate back to the same view by returning void
or null
and render the include conditionally.
<ui:include src="#{bean.editmode ? 'edit' : 'view'}.xhtml" />
但是,如果您需要支持GET而不是POST(则需要将<h:commandButton>
替换为<h:button>
),则此方法不起作用.
This however doesn't work if you require to support GET instead of POST (for which you would need to replace <h:commandButton>
by <h:button>
by the way).
这篇关于使用setPropertyActionListener查看范围限定的受管bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!