Getting backing bean value with Javascript

≯℡__Kan透↙ 提交于 2019-12-28 02:05:08

问题


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:

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

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

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.

How it's working: If I add the @PostConstruct annotation 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?


回答1:


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:

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

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

Basically, you want to let JSF re-render that piece of 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.




回答2:


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.

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

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

and you can use this parameter in xhtml:

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

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


来源:https://stackoverflow.com/questions/14966205/getting-backing-bean-value-with-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!