View scoped managed bean with setPropertyActionListener

后端 未结 1 405
暗喜
暗喜 2021-01-15 13:26

I cant seem to get the view scoped managed bean to work with setPropertyActionListener:

   

        
相关标签:
1条回答
  • 2021-01-15 14:00

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

    0 讨论(0)
提交回复
热议问题