При создании нового вида создается новый компонент с областью видимости. Целевое представление содержит другой экземпляр bean-объекта области видимости, отличное от того, где свойство было установлено методом действия в начальном представлении с формой.
Это на первый взгляд действительно не интуитивно понятно, но так работает область видимости. Бин с областью видимости живет столько же, сколько и вид. В конце концов, это имеет смысл.
Ваша лучшая ставка - <f:param>
вместо <f:setPropertyActionListener>
, и пусть целевое представление установит ее на <f:viewParam>
.
1010 * Е.Г. *
<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>
).