SelectOneMenu 标记中的 JSF 2.0 Ajax 侦听器不起作用

发布于 2024-12-01 04:23:02 字数 2370 浏览 0 评论 0原文

问题已解决!! 我的支持 bean 上有一个验证错误,告诉我如下内容: “空转换器”的转换错误设置值“非洲 (AFR)”。

由于 JSF 生命周期,我的 backingbean 上的侦听器方法未被调用,


我在使用 JSF2 时遇到了问题。 我有一个带有 ajax 标签的 selectOneMenu 标签,当其值更改时应该触发侦听器。 xhtml 页面如下所示(删除了一些内容)

<h:selectOneMenu id="selectedContinent" value="#{searchExtendedAction.destination.continent}">
            <f:selectItems value="#{searchExtendedAction.continents}" />
            <f:ajax render="locationSelector" listener="#{searchExtendedAction.doUpdateLocations}" />
</h:selectOneMenu>

在我的支持 bean 中,我有以下内容(保留了一些属性):

@ManagedBean
@SessionScoped
public class SearchExtendedAction implements Serializable{


// Left some properties out


    @Valid
    private Location departure;

    @PostConstruct
    public void init(){
        System.err.println("INIT called");
        allContinents = continentService.getAllContinents();
    }

    @EJB
    private ContinentService continentService;

    public void doExtendedSearch()
    {
        System.err.println("SEARCH");
    }
    public void doUpdateLocations(AjaxBehaviorEvent event)
    {
        System.err.println("BONZAI");
    }

    public List<SelectItem> getContinents()
    {
        List<SelectItem> continents= new ArrayList<SelectItem>();
        continents.add(new SelectItem("--- Select Continent ---"));

        for(Continent c : continentService.getAllContinents()){
            continents.add(new SelectItem(c.getName()));
        }

        return continents;
    }
}

现在,当我从 selectOneMenu 中选择一个值时,将触发 HTTP Post。我知道这一点是因为我的 PostConstruct 方法被调用并且消息在我的控制台中弹出。但监听者没有被调用。我不知道为什么。

有关我正在使用的技术的更多信息:

16:21:08,282 INFO  [AbstractServer] Starting: JBossAS [6.1.0.Final "Neo"]
16:21:11,725 INFO  [ServerInfo] Java version: 1.7.0,Oracle Corporation
16:21:11,725 INFO  [ServerInfo] Java Runtime: Java(TM) SE Runtime Environment (build 1.7.0-b147)
16:21:11,725 INFO  [ServerInfo] Java VM: Java HotSpot(TM) 64-Bit Server VM 21.0-b17,Oracle Corporation
16:21:11,726 INFO  [ServerInfo] OS-System: Windows 7 6.1,amd64
16:21:19,067 INFO  [AbstractServerConfig] JBoss Web Services - Stack CXF Server 3.4.1.GA
16:21:19,981 INFO  [JSFImplManagementDeployer] Initialized 3 JSF configurations: [Mojarra-1.2, MyFaces-2.0, Mojarra-2.0]

PROBLEM SOLVED!!
There was a validationerror on my backing bean telling me something like this:
Conversion Error setting value 'Africa (AFR)' for 'null Converter'.

Because of the JSF lifesycle the listener method on my backingbean wasn't called


I'm havinga problem with JSF2.
I have a selectOneMenu tag with an ajax tag that should fire a listener when its value is changed. The xhtml page looks like the following (stripped some things out)

<h:selectOneMenu id="selectedContinent" value="#{searchExtendedAction.destination.continent}">
            <f:selectItems value="#{searchExtendedAction.continents}" />
            <f:ajax render="locationSelector" listener="#{searchExtendedAction.doUpdateLocations}" />
</h:selectOneMenu>

In my backing bean I have the following (Left some properties out):

@ManagedBean
@SessionScoped
public class SearchExtendedAction implements Serializable{


// Left some properties out


    @Valid
    private Location departure;

    @PostConstruct
    public void init(){
        System.err.println("INIT called");
        allContinents = continentService.getAllContinents();
    }

    @EJB
    private ContinentService continentService;

    public void doExtendedSearch()
    {
        System.err.println("SEARCH");
    }
    public void doUpdateLocations(AjaxBehaviorEvent event)
    {
        System.err.println("BONZAI");
    }

    public List<SelectItem> getContinents()
    {
        List<SelectItem> continents= new ArrayList<SelectItem>();
        continents.add(new SelectItem("--- Select Continent ---"));

        for(Continent c : continentService.getAllContinents()){
            continents.add(new SelectItem(c.getName()));
        }

        return continents;
    }
}

Now when I pick a value from my selectOneMenu a HTTP Post is fired. And I know this because my PostConstruct method is called and the message pops up in my console. But the listener is not called. And I have no idea why.

Some more information about the technologies I'm using:

16:21:08,282 INFO  [AbstractServer] Starting: JBossAS [6.1.0.Final "Neo"]
16:21:11,725 INFO  [ServerInfo] Java version: 1.7.0,Oracle Corporation
16:21:11,725 INFO  [ServerInfo] Java Runtime: Java(TM) SE Runtime Environment (build 1.7.0-b147)
16:21:11,725 INFO  [ServerInfo] Java VM: Java HotSpot(TM) 64-Bit Server VM 21.0-b17,Oracle Corporation
16:21:11,726 INFO  [ServerInfo] OS-System: Windows 7 6.1,amd64
16:21:19,067 INFO  [AbstractServerConfig] JBoss Web Services - Stack CXF Server 3.4.1.GA
16:21:19,981 INFO  [JSFImplManagementDeployer] Initialized 3 JSF configurations: [Mojarra-1.2, MyFaces-2.0, Mojarra-2.0]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

踏月而来 2024-12-08 04:23:02

现在,当我从 selectOneMenu 中选择一个值时,就会触发 HTTP Post。我知道这一点是因为我的 PostConstruct 方法被调用并且消息在我的控制台中弹出。

会话作用域 bean 的 @PostConstruct 此时被触发是不正常的。每当您在会话中第一次请求视图时,它应该在 bean 构造期间仅触发一次。您确定 @SessionScoped 的类型为 javax.faces.bean.SessionScoped,因此不是 javax.enterprise.context。会话范围?

更新:根据评论,该问题已得到解决。但是并没有解决监听器没有被调用的具体问题。结果发现发生了验证错误。当所选项目的 equals() 方法在应用请求值阶段没有为列表中的任何项目返回 true 时,就会发生这种情况。 来获得确切的验证错误

<h:messages id="messages" />

render 属性中

<f:ajax render="locationSelector messages" ... /> 

您可以通过提供 a 并将其 ID 包含在与具体问题无关的 ,@ViewScoped 是为此更好的选择。这样,同一浏览器会话中的每个浏览器窗口/选项卡都有自己的 bean 实例。也就是说,会话范围内的 bean 在同一会话中的所有浏览器窗口/选项卡之间共享,这可能会导致“wtf?”因此,这种行为对用户体验不利。

Now when I pick a value from my selectOneMenu a HTTP Post is fired. And I know this because my PostConstruct method is called and the message pops up in my console.

It is not normal that the @PostConstruct of a session scoped bean is fired at that moment. It should be fired only once during bean's construction whenever you request the view for the first time in the session. Are you sure that the @SessionScoped is of type javax.faces.bean.SessionScoped and thus not javax.enterprise.context.SessionScoped?

Update: as per the comments, that issue has been fixed. However, it didn't solve the concrete problem of the listener not being invoked. It turns out that a validation error has occurred. That can happen when the equals() method of the selected item doesn't return true for any of the items in the list during the apply request values phase. You could get the exact validation error by supplying a

<h:messages id="messages" />

and include its ID in the render attribute

<f:ajax render="locationSelector messages" ... /> 

Unrelated to the concrete problem, the @ViewScoped is a better choice for this. This way every browser window/tab within the same browser session has its own instance of the bean. A session scoped the bean is namely shared between all browser windows/tabs within the same session which may lead to "wtf?" behaviour which is thus bad for User Experience.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文