Odd behavior of rich:datagrid value attribute
balteo Apr 1, 2011 10:46 AMHello,
I have an issue with my rich:datagrid since I switched the scope of my spring bean to a custom view scope.
The issue is that the name of the bean (i.e. "galerieView") is ignored by richfaces! Whatever is put instead of the "galerieView" string is accepted and no facelets error is returned but the value of sculptures in "#{galerieView.sculptures}" is treated as if it were empty and my page is empty. Very odd...
However, if I change ".sculptures" to something else, I get a facelets error.
Here is my jsf code:
<rich:dataGrid value="#{galerieView.sculptures}" var="sculpture" columns="3" styleClass="datagrid-galerie" iterationStatusVar="iterations">
<h:panelGroup rendered="#{!iterations.last}">
<p>
<pretty:link mappingId="sculptureAction" styleClass="miniature-link">
<f:param value="#{view.locale.language}"/>
<f:param value="#{jbm:normaliserURL(sculpture.sculpturei18nMap[view.locale.language].titre)}" />
<f:param value="#{sculpture.sculptureID}" />
<h:graphicImage value="#{initParam['com.jeanbaptistemartin.static.url']}/#{sculpture.photoMiniature}" styleClass="miniature-image" alt="#{sculpture.sculpturei18nMap[view.locale.language].titre}, #{sculpture.sculpturei18nMap[view.locale.language].matiere}, #{jbm:renvoyerAnnee(sculpture.annee)}."/>
</pretty:link>
</p>
<p>
<pretty:link mappingId="sculptureAction" styleClass="miniature-link-text">
<f:param value="#{view.locale.language}"/>
<f:param value="#{jbm:normaliserURL(sculpture.sculpturei18nMap[view.locale.language].titre)}" />
<f:param value="#{sculpture.sculptureID}" />
<h:outputText value="#{sculpture.sculpturei18nMap[view.locale.language].titre}, " />
<h:outputText value="#{sculpture.sculpturei18nMap[view.locale.language].matiere}" />
</pretty:link>
</p>
</h:panelGroup>
<h:panelGroup rendered="#{iterations.last}" styleClass="miniature-link">
<p id="sellette">
<img src="#{facesContext.externalContext.requestContextPath}/images/200x200.gif" class="miniature-image" alt="" onclick="slideUp()"/>
</p>
<div class="formulaireInscriptionSculpture">
<h:form id="formulaireInscriptionSculpture" prependId="false">
<ui:include src="WEB-INF/include/formulaire-inscription-sculpture.xhtml"/><!-- todo: ne fonctionne pas... -->
</h:form>
</div>
</h:panelGroup>
<rich:jQuery name="slideUp" query="slideUp({duration:'slow'});slideDownForm()" selector="#sellette"/>
<rich:jQuery name="slideDownForm" query="slideDown({duration:'slow'})" selector="div.formulaireInscriptionSculpture" />
<rich:jQuery name="slideDownSellette" query="slideDown({duration:'slow'})" selector="#sellette"/>
</rich:dataGrid>
and my spring bean:
@Component("galerieView")
@Scope("view")
@URLMapping(id = "galerieAction", parentId = "rootAction", pattern = "galerie", viewId = "/galerie.jsf")
public class GalerieView {
private static transient Logger log = Logger.getLogger("com.jeanbaptistemartin.view");
private JbmService service;
private List<Sculpture> sculptures;
public GalerieView() {
log.info("GalerieView()");
}
@Autowired
public GalerieView(JbmService service) {
log.info("GalerieView(JbmService service)");
this.service = service;
}
@URLAction(onPostback = false)
public String afficheSculptures() {
log.debug("afficheSculptures");
this.sculptures = service.findAllSculptures();
this.sculptures.add(null);
return "/galerie.xhtml";
}
public List<Sculpture> getSculptures() {
return sculptures;
}
public void setSculptures(List<Sculpture> sculptures) {
this.sculptures = sculptures;
}
}
And finally my viewScope implementation class:
public class ViewScope implements Scope {
private static transient Logger log = Logger.getLogger("com.jeanbaptistemartin.util");
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
log.debug("get");
log.debug("name: " + name);
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
if (viewMap.containsKey(name)) {
return viewMap.get(name);
} else {
Object object = objectFactory.getObject();
viewMap.put(name, object);
log.debug("object: " + object);
return object;
}
}
@Override
public Object remove(String name) {
log.debug("remove");
log.debug("name: " + name);
return FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove(name);
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
// Do nothing
}
@Override
public Object resolveContextualObject(String key) {
log.debug("resolveContextualObject");
log.debug("key: " + key);
return null;
}
@Override
public String getConversationId() {
log.debug("getConversationId");
return null;
}
}
Has anyone any idea why I get this behavior?
J.
PS I don't get this behavior with scope=session.