使用 setPropertyActionListener 查看作用域托管 bean

发布于 2024-11-24 05:45:35 字数 360 浏览 2 评论 0原文

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

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

如果 companyHolder 是会话或请求作用域,则此方法可以正常工作,但如果其视图作用域是作用域,则不起作用。这是正常的吗?

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>

This works fine if companyHolder is session or request scoped but doesnt work if its view scoped. Is this normal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放赐 2024-12-01 05:45:35

创建新视图时,也会创建一个全新的视图作用域 bean。目标视图保存的视图作用域 bean 的实例与通过表单的初始视图上的操作方法设置属性的实例不同。

乍一看确实不直观,但这就是视图范围的工作原理。视图作用域 bean 的寿命与视图的寿命一样长。毕竟这是有道理的。

最好的选择是使用 而不是 并让目标视图通过 设置它

例如,

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

and

@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(为此您需要将 替换为 ,则此方法不起作用顺便一提)。

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.

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.

Your best bet is using <f:param> instead of <f:setPropertyActionListener> and let the target view set it by <f:viewParam>.

E.g.

<h:commandButton value="Edit"  action="edit-company.xhtml">
    <f:param name="companyId" value="#{company.id}"/>            
</h:commandButton>

with

<f:metadata>
    <f:viewParam name="companyId" value="#{bean.company}" required="true" />
</f:metadata>

and

@ManagedBean
@ViewScoped
public class Bean {

    private Company company;

    // ...
}

and

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

    // ...
}

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文