Primefaces ajax 根据 backbean 结果更新不同的面板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14779852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 10:56:47  来源:igfitidea点击:

Primefaces ajax update different panels according to backbean result

ajaxjsfprimefaces

提问by RSoliveira

I'm new to JSF, Primefaces and Ajax, so what i'm trying to do is update one panel if a validation on my back bean is true and update another panel when it's false.

我是 JSF、Primefaces 和 Ajax 的新手,所以我想要做的是在我的后台 bean 上的验证为真时更新一个面板,并在它为假时更新另一个面板。

<h:panelGroup id="panel1">
    ...
    <h:commandButton id="btn1" action="#{bean.validate}">
        <p:ajax process="panel1" update="panel1"/>
    </h:commandButton>
</h:panelGroup>

<h:panelGroup id="panel2">
    ...
</h:panelGroup>

Back Bean:

背豆:

public void validate() {
    ...
    if(validatecondition) {
        // Update panel 1
    } else {
        // update panel 2
    }
}

So is it possible to do this using ajax? Thanks in advance!!

那么可以使用ajax来做到这一点吗?提前致谢!!

回答by kolossus

Sure, two ways. Since you're using primefaces, the easier of two options would be

当然,两种方式。由于您使用的是primefaces,因此两个选项中较容易的一个是

  1. Use the RequestContextobject to update the panels selectively. Your code will look like this:

     public void validate() {
       RequestContext context = RequestContext.getCurrentInstance();
       if(validatecondition) {
         context.update("panel1");
       } else {
         context.update("panel2");
       }
    }
    
  2. JSF PartialViewContextcan do the same job, with just a little more typing

    FacesContext ctxt = FacesContext.getCurrentInstance(); //get your hands on the current request context
         if(validatecondition) {
             ctxt.getPartialViewContext().getRenderIds().add("panel1");
           } else {
             ctxt.getPartialViewContext().getRenderIds().add("panel2");
           }
    
  1. 使用RequestContext对象有选择地更新面板。您的代码将如下所示:

     public void validate() {
       RequestContext context = RequestContext.getCurrentInstance();
       if(validatecondition) {
         context.update("panel1");
       } else {
         context.update("panel2");
       }
    }
    
  2. JSFPartialViewContext可以做同样的工作,只需多一点输入

    FacesContext ctxt = FacesContext.getCurrentInstance(); //get your hands on the current request context
         if(validatecondition) {
             ctxt.getPartialViewContext().getRenderIds().add("panel1");
           } else {
             ctxt.getPartialViewContext().getRenderIds().add("panel2");
           }
    

The getRenderIds()call returns a list of component Ids that JSF will update via ajax on completion of the response. This is basically what RequestContextin primefaces will do under the hood.

getRenderIds()调用返回一个组件 Id 列表,JSF 将在响应完成时通过 ajax 更新这些 Id。这基本上就是RequestContextprimefaces 将在引擎盖下做的事情。

回答by partlov

This is possible, and it is also easy if you are using PrimeFaces. But first I suggest you to make your button little more "primefaces like". Reorganize it to something like this:

这是可能的,如果您使用 PrimeFaces,这也很容易。但首先我建议你让你的按钮更像“primefaces”。将其重新组织为如下所示:

<p:commandButton id="btn1" action="#{bean.validate}" process="panel1"/>

PrimeFaces button is AJAX enabled by default, so there is no need for additional tags. Remove update attribute (as we will do that in backing bean).

PrimeFaces 按钮默认启用 AJAX,因此不需要额外的标签。删除更新属性(因为我们将在支持 bean 中这样做)。

Now, your method in backing bean:

现在,您在支持 bean 中的方法:

public void validate() {
  // ...
  if(validatecondition) {
    RequestContext.getCurrentInstance().update("panel1");
  } else {
    RequestContext.getCurrentInstance().update("panel2");
  }
}

RequestContextis one very useful class which you can use to update, reset fields or to execute some JavaScript after AJAX requests. In this example it is used just to conditionally update panel1 or panel2.

RequestContext是一个非常有用的类,您可以使用它来更新、重置字段或在 AJAX 请求后执行一些 JavaScript。在此示例中,它仅用于有条件地更新 panel1 或 panel2。

回答by Tony Shih

JSF page code will be following in the backing bean the contents in a input will check and enable the correct panel accordingly. enter 1 in the input will activate panel 1, enter 2 for panel 2 and leave blank for both panels.

JSF 页面代码将跟随在支持 bean 中,输入中的内容将相应地检查并启用正确的面板。在输入中输入 1 将激活面板 1,为面板 2 输入 2 并为两个面板留空。

JSF is an excellent specification for enterprise application development it provides greater flexibility and separation of concern. Where you need to leave the user interface elements away from your business logic components. My solution is adheres to that principal by not referencing to UI element ids in the backing bean.

JSF 是企业应用程序开发的优秀规范,它提供了更大的灵活性和关注点分离。您需要将用户界面元素与业务逻辑组件分开的地方。我的解决方案是通过不引用支持 bean 中的 UI 元素 ID 来遵守该原则。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        Hello from Facelets
        <h:form id="frm" >

            <h:commandButton value="click me" action="#{test2.aa()}">                
                <f:ajax execute="@form" render=":mainpanel" ></f:ajax> 
            </h:commandButton>
            <h:inputText id="intest" value="#{test2.selection}"></h:inputText> 

        </h:form>
        <h:panelGroup id="mainpanel">
            <h:panelGroup id="panel1" rendered="#{test2.prop1=='v'}">panel1
                <h:outputLabel id="lbl1" value="#{test2.prop1}" ></h:outputLabel>                
            </h:panelGroup>
            <h:panelGroup id="panel2" rendered="#{test2.prop2=='v'}">panel2
                <h:outputLabel id="lbl2" value="#{test2.prop2}"></h:outputLabel>
            </h:panelGroup>
        </h:panelGroup>
    </h:body>
</html> 

Backing bean code simple as possible I have used session scope also possible in request scope.

支持 bean 代码尽可能简单 我在请求范围中也使用了会话范围。

package test;

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;

@Named(value = "test2")
@SessionScoped
public class test2 implements Serializable {


    String prop1;
    String prop2;
    String selection;

    public String getProp1() {
        return prop1;
    }

    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    public String getProp2() {
        return prop2;
    }

    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }

    public test2() {
        prop1 = "v";
        prop2 = "v";
        selection = "";
    }

    public String getSelection() {
        return selection;
    }

    public void setSelection(String selection) {
        this.selection = selection;
    }

    public String aa() {
        if ("".equals(selection)) {
            prop1 = "v";
            prop2 = "v";
            return "";
        } else if ("1".equals(selection)) {
            prop1 = "v";
            prop2 = "h";
            return "";
        } else if ("2".equals(selection)) {
            prop1 = "h";
            prop2 = "v";
            return "";
        }
        return "";
    }
}