【问题标题】:execution-order in h:form with h:selectOneMenu, h:outputText and f:ajaxh:form 中的执行顺序与 h:selectOneMenu、h:outputText 和 f:ajax
【发布时间】:2013-05-07 11:03:03
【问题描述】:

我搜索了很多关于这个主题的内容,但我没有找到可以帮助我解决问题的解决方案。 我有一个包含“类别”对象列表的表单,这些对象作为 selectItems 放置在 selectOneMenu 和 outputText(使用与 selectOneMenu 相同的 bean)。转换器完成了他的工作,所有类别名称都正确显示。使用 ajax 标记,表单会更改 selectOneMenu onchange 中的值。这也有效,bean-property 已更新!但现在我想在更改后立即在 outputText 中显示选定的类别。我该怎么办???

要查看 outputText 中的新值,我必须刷新页面。 (KategorieBean 是 SessionScoped)

outputText-value 的 getter 总是在 bean 的类别属性更新之前调用。

view.xhtml:

    <h:form>
        Wähle eine Kategorie:
        <h:selectOneMenu 
                            value="#{kategorieBean.kategorie}">
            <f:selectItem
                            itemLabel="Wählen..."
                            itemValue="#{null}"/>
            <f:selectItems 
                            value="#{kategorieBean.allKategories}"
                            var="k" 
                            itemLabel="#{k.name}"
                            itemValue="#{k}" />     
            <f:ajax 
                            event="change"
                            execute="@form"
                            render="result"
                            listener="#{kategorieBean.kategorieChangeListener}"/>
        </h:selectOneMenu>
        Ausgewählte Kategorie:      
        <h:outputText id="result" value="#{kategorieBean.kategorie.name}" />
    </h:form>

我还尝试在 ajax-tag 中使用监听器。侦听器工作,但我仍然有执行顺序的问题:(

类别豆:

package xxx.bean;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import xxx.hibernate.entity.Kategorie;
import xxx.hibernate.dao.KategorieDao;

@ManagedBean(name="kategorieBean")
@SessionScoped
public class KategorieBean{

private Kategorie kategorie;
private KategorieDao kategorieDao;
private List<Kategorie> allKategories;

@PostConstruct
public void init(){
    kategorie = null;
    kategorieDao = new KategorieDao();
    allKategories = kategorieDao.getAllKategories();
}

public List<Kategorie> getAllKategories() {
    return allKategories;
}
public void setAllKategories(List<Kategorie> allKategories) {
    this.allKategories = allKategories;
}

public Kategorie getKategorie() {
    if (kategorie != null)
        System.out.println("getter kategorie: name=" + kategorie.getName());
    else
        System.out.println("getter kategorie: kategorie=null");
    return kategorie;
}
public void setKategorie(Kategorie kategorie) {
    System.out.println("setter kategorie: name=" + kategorie.getName());
    this.kategorie = kategorie;
}
    public void kategorieChangeListener(AjaxBehaviorEvent e) {
        System.out.println("kategoriename: " + kategorie.getName());
    }

类别转换器:

package xxx.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

import xxx.bean.KategorieBean;
import xxx.hibernate.entity.Kategorie;

@FacesConverter(forClass = Kategorie.class)
public class KategorieConverter implements Converter{

    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        System.out.println("Converter: getAsObject");
        KategorieBean kB = (KategorieBean) FacesContext.getCurrentInstance().
                getExternalContext().getSessionMap().get("kategorieBean");
        for (Kategorie k : kB.getAllKategories()){
            if (k.getKategorieId() == Long.valueOf(value))
                return k;
        }
        return null;
    }

    public String getAsString(FacesContext context, UIComponent component, Object value) {
        System.out.println("Converter: getAsString");
        return String.valueOf(((Kategorie) value).getKategorieId());
    }
}

控制台输出(初始):

  • 休眠:选择this_.kategorie_id作为kategori1_1_0_, this_.beschreibung 为 beschrei2_1_0_,this_.liferay_company_id 为 liferay3_1_0_, this_.liferay_group_id as liferay4_1_0_, this_.name as name5_1_0_, this_.parent_id as parent6_1_0_ from usushop_kategorie 这_
  • getter 类别:kategorie=null
  • 转换器:getAsString
  • 转换器:getAsString
  • 转换器:getAsString
  • 转换器:getAsString
  • 转换器:getAsString
  • 转换器:getAsString
  • getter 类别:kategorie=null

selectOneMenu 中的值更改后的控制台输出:

  • 转换器:getAsObject
  • getter 类别:kategorie=null
  • setter 类别:name=Kategorie4
  • 类别名称:类别4
  • getter 类别:name=Kategorie4

【问题讨论】:

    标签: ajax jsf selectonemenu


    【解决方案1】:

    可以使用 Richface 的 a4j(ajax4jsf)

    <%@taglib prefix="a4j" uri="http://richfaces.org/a4j"%>
    
    
    
    <h:form>
        <h:selectOneMenu  value="#{kategorieBean.kategorie}">
                <f:selectItem
                                itemLabel="Wählen..."
                                itemValue="#{null}"/>
                <f:selectItems 
                                value="#{kategorieBean.allKategories}"
                                var="k" 
                                itemLabel="#{k.name}"
                                itemValue="#{k}" />     
                <a4j:support event="onchange" action="#{bean.SomeAction}" reRender="result"/>
            </h:selectOneMenu>
    <h:panelGroup id="result">
        <h:outputText  value="#{kategorieBean.kategorie.name}" />
    </h:panelGroup>
    </h:form>
    

    【讨论】:

    • 或者你可以使用 标签的 render 属性
    • 谢谢!但我忘了告诉我将在我的项目中使用 icefaces。冰面也有解决方案吗? 标签的 render 属性不会改变执行顺序:( ...我正在使用 liferay-faces-bridge 3.1.1,因为我想为 liferay 编写一个 portlet
    • I don't know abour icefaces :( 顺便问一下,你有没有将 outputText 的 ID(即结果)作为渲染属性的值?
    • 你应该使用 标签而不是 标签
    • 是的,我给 outputText 提供了 ID“result”,并在 f:ajax 标记中使用了属性 render="result" ... getter 的执行顺序仍然没有变化,并且二传手。我还使用了 h:head 标签。我要疯了
    猜你喜欢
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2015-08-02
    • 2011-06-15
    相关资源
    最近更新 更多