使用 Javascript 获取支持 bean 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14966205/
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-08-24 18:29:25  来源:igfitidea点击:

Getting backing bean value with Javascript

javascriptjsfjsf-2

提问by ?mer Faruk Almal?

JSF 2.0, Mojarra 2.0.1, PrimeFaces 3.4.1

JSF 2.0、Mojarra 2.0.1、PrimeFaces 3.4.1

There are similar questions but I need sth. else; javascript function has to wait for the backing bean method, which is filling the variable that wanted to be pulled from js function. What I want to say is:

有类似的问题,但我需要…… 别的; javascript 函数必须等待支持 bean 方法,该方法正在填充想要从 js 函数中提取的变量。我想说的是:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad()"/>

Assuming js function just getting the value and printing it to the screen.

假设 js 函数只是获取值并将其打印到屏幕上。

function afterLoad() {    
    alert("#{statusBean.size}");
}

And here is the birthday kid:

这是生日孩子:

@ManagedBean
@ViewScoped
public class StatusBean {
    public int size=0;
    List<Status> panelList = new ArrayList<Status>();
    public void getStatuses() {
        this.panelList = fillList();
        this.size = panelList.size(); //Assuming 3
    }
    //getter and setters
}

So function alerts the size as 0 which is the initial value of it, while we're expecting to see 3.

所以函数提醒大小为 0,这是它的初始值,而我们期望看到 3。

How it's working:If I add the @PostConstructannotation to bean's head surely it gets the correct size, because bean is already constructed before the page load. But this means redundant processes, value just needed after the commandlink action. So how to postpone the js function? Any ideas?

它是如何工作的:如果我将@PostConstruct注释添加到 bean 的头部,它肯定会获得正确的大小,因为 bean 在页面加载之前已经构造好了。但这意味着冗余进程,仅在 commandlink 操作之后才需要值。那么如何推迟js功能呢?有任何想法吗?

回答by BalusC

JSF/EL and HTML/JS doesn't run in sync. Instead, JSF/EL run in webserver and produces HTML/JS which in turn runs in webbrowser. Open page in browser, rightclick and View Source. You see, there's no single line of JSF/EL. It's one and all HTML/JS. In place of your JS function, you'll see:

JSF/EL 和 HTML/JS 不同步运行。相反,JSF/EL 在 webserver 中运行并生成 HTML/JS,后者又在 webbrowser 中运行。在浏览器中打开页面,右键单击并查看源代码。你看,没有一行 JSF/EL。它是一种和所有的 HTML/JS。代替您的 JS 函数,您将看到:

function afterLoad() {    
    alert("0");
}

Exactly this JS function get invoked on complete of your command button action. So the result is fully expected.

正是在您的命令按钮操作完成时调用此 JS 函数。所以结果完全在意料之中。

Basically, you want to let JSF re-render that piece of JS.

基本上,您希望让 JSF 重新渲染那段 JS。

<p:commandLink action="#{statusBean.getStatuses}" update="afterLoad" oncomplete="afterLoad()"/>
<h:panelGroup id="afterLoad">
    <h:outputScript>
        function afterLoad() {    
            alert("#{statusBean.size}");
        }
    </h:outputScript>
</h:panelGroup>

Depending on the concrete functional requirement, which you didn't tell anything about, there may be more elegant ways. For example, RequestContext#execute(), <o:onloadScript>, etc.

根据您没有提及的具体功能需求,可能有更优雅的方法。例如RequestContext#execute()<o:onloadScript>、 等。

回答by partlov

EL in your JavaScript is calculated when page is rendered and you can update its container (if it is in some JSF component), but I would suggest another approach.

JavaScript 中的 EL 是在页面呈现时计算的,您可以更新其容器(如果它在某个 JSF 组件中),但我建议采用另一种方法。

As you are making AJAX request, you can add callback parameter in getStatuses()method. You can use Primefaces's RequestContextutility method addCallBackParam()for this:

当您发出 AJAX 请求时,您可以在getStatuses()方法中添加回调参数。您可以为此使用 Primefaces 的RequestContext实用方法addCallBackParam()

public void getStatuses() {
    this.panelList = fillList();
    this.size = panelList.size();
    RequestContext.getCurrentInstance().addCallBackParam("size", this.size);
}

and you can use this parameter in xhtml:

你可以在 xhtml 中使用这个参数:

<p:commandLink action="#{statusBean.getStatuses}" oncomplete="afterLoad(xhr, status, args)"/>

<script type="text/javascript">
  function afterLoad(xhr, status, args) {    
    alert(args.size);
  }
</script>