Просмотр управляемого компонента с заданной областью действия с помощью setPropertyActionListener

Кажется, я не могу заставить управляемый компонент с областью представления работать с setPropertyActionListener:

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

Это отлично работает, если companyHolder находится в области сеанса или запроса, но не работает, если его область видимости ограничена. Это нормально?


person DD.    schedule 18.07.2011    source источник


Ответы (1)


Совершенно новый 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);
       }
    }

    // ...
}

В качестве совершенно другой альтернативы вы также можете просто вернуться к тому же представлению, вернув void или null и отобразить включение условно.

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

Однако это не работает, если вам требуется поддержка GET вместо POST (для чего, кстати, вам нужно будет заменить <h:commandButton> на <h:button>).

person BalusC    schedule 18.07.2011
comment
Если я выберу метод param, нужно ли мне начинать добавлять меры безопасности для людей, публикующих параметры для чужих компаний? - person DD.; 18.07.2011
comment
Я бы сказал, используйте условное включение. - person BalusC; 18.07.2011