如何执行在服务器/客户端使用回调参数的javascript函数



我使用JSF 2.2,Primefaces 6.0和CDI。我的一个页面包含一个脚本,它有两个javascript函数(其中一个创建图表,第二个向图表提供新数据(和一个简单的表单,用作过滤器。我已经删减了我的代码(看下面(,向您展示了我的代码中最重要的部分。

我想实现这样的事情:

  • 第一次加载/打开页面时,第一个javascript函数应该运行(自动运行,无需按下任何按钮或链接(,并且应该使用我在cdi bean中设置的几个回调参数。
  • 每次按下按钮时,第二个 javascript 函数都应该运行,并且应该使用我在 CDI bean 中设置的几个回调参数。

你怎么看,上面的机制是基于通过RequestContext将一些值从CDI bean传递给javascript的。为了实现这一点,我基于素数文档(第11.1章(。到目前为止,我已经:

  • 为 CDI Bean 的 init() 方法(具有@PostConstruct注释(中的第一个函数创建了多个回调参数;
  • oncomplete 属性添加到<p:commandButton>组件,该组件使用 args 参数调用函数的第二个。我想传递给第二个函数的值是在actionFilterButton()方法中准备的,我在按钮的属性中调用action该方法。

目前我的页面是这样的:

  • 加载/打开页面时,不会执行第一个 javascript 函数。
  • 当我按下按钮时,第二个 javascript 函数被执行,它将回调参数的值保存在 javascript 变量中。

你怎么看,问题是第一阶段。当我打开页面时,第一个javascript函数没有执行。

如何调用第一个 JavaScript 函数?

我试了什么?

  • 我尝试在服务器端调用第一个 javascript 函数,在 init() 方法中调用requestContext.execute("firstFunction(args)");,希望它能正常工作,但它不起作用,并且在我使用该表单时会破坏我的表单。 我不确定我是否可以像在服务器端那样args放(实际上我不确定它是否正确解释(。
  • 我还尝试在脚本末尾调用firstFunction()(如下所示(,但它也不起作用。

我的 xhtml 页面:

<!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:ui="http://java.sun.com/jsf/facelets" 
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:head> 
    <!-- loading css -->
</h:head>
<h:body>
    <div id="container" style="height: 750px; width: 100%; margin: 0 auto;"/>
<script type="text/javascript">
    //<![CDATA[
    //Declaration of variables
    var chart;
    var data1;
    var data2;
    var data3;
    function firstFunction(args) {  
        $(function() {
            data1 = JSON.parse(args.data1);
            data2 = JSON.parse(args.data2);
            data3 = JSON.parse(args.data3);
            //Other operations          
        });
    }
    function secondFunction(args) {
        $(function() {
            data1 = JSON.parse(args.data1);
            data2 = JSON.parse(args.data2);
            data3 = JSON.parse(args.data3);
            //Other different operations            
        });
    }
    firstFunction(args);
    //]]>
</script>
<br/>
<h:form id="filterForm">
    <p:selectManyCheckbox id="filter" value="#{chart2Controller.selectedKindOfNetwork}" layout="responsive" columns="4">
        <p:ajax update="filterButton" />
        <f:selectItems value="#{chart2Controller.kindOfNetwork}" var="kindOfNetwork" itemLabel="#{kindOfNetwork}" itemValue="#{kindOfNetwork}" />
    </p:selectManyCheckbox>
    <br/>
    <p:commandButton id="filterButton" value="Filter" action="#{chart2Controller.actionFilterButton()}"
                    disabled="#{!chart2Controller.visibilityFilterButton}"
                    update="filterForm"
                    oncomplete="secondFunction(args);"/>    
</h:form>
</h:body>       
</html>                      

我的 CDI 豆的一部分:

@Named
@ViewScoped
public class Chart2Controller implements Serializable {
    /**
     * Start method.
     */
    @PostConstruct
    public void init() {
        initData();     
        //This isn't work.
        //requestContext.execute("firstFunction(args)");
    }
    /**
     * Downloading the data from the database.
     */
    private void initData(){

        /*
         * Sending the query to the database including the filter options of the form,
         * saving the result and preparing the data basing on the result.
         */
        //Preparing the callback parameters.
        requestContext = RequestContext.getCurrentInstance();
        requestContext.addCallbackParam("data1", data1);
        requestContext.addCallbackParam("data2", data2);
        requestContext.addCallbackParam("data3", data3);
    }
    /**
     * Action for the filter button.
     */
    public void actionFilterButton(){
        initData(); 
    }   
    /**
     * Visibility for filter button.
     */
    public boolean getVisibilityFilterButton(){     
        //return true or false.
    }   
    //Getter and Setter
    private static final long serialVersionUID = -8128862377479499815L;
    @Inject
    private VisualizationService visualizationService;
    private RequestContext requestContext;
    private List<ChartModel2> data;
    private List<String> kindOfNetwork;
    private List<String> selectedKindOfNetwork;
    private String data1;
    private String data2;
    private String data3;
}

我相信将其包装为 IIFE 可以解决问题。 如果您加载太快并且需要 DOM ,请尝试类似 on load .

(function firstFunction(args) {  
    $(function() {
        data1 = JSON.parse(args.data1);
        data2 = JSON.parse(args.data2);
        data3 = JSON.parse(args.data3);
        //Other operations          
    });
})();

我刚刚找到了灵魂。实际上有两种解决方案:服务器端(我推荐(和客户端。我的问题是这个javascript行:firstFunction(args);。未正确解释args参数。


在服务器端

首先,我更改了我的 javascript 函数的参数。我没有使用args参数,而是使用了三个参数(每个变量一个(。目前,脚本应如下所示:

<script type="text/javascript">
    //<![CDATA[
    //Declaration of variables
    var chart;
    var data1;
    var data2;
    var data3;
    function firstFunction(data1p, data2p, data3p) {    
        $(function() {
            data1 = JSON.parse(data1p);
            data2 = JSON.parse(data2p);
            data3 = JSON.parse(data3p);
            //Other operations          
        });
    }
    function secondFunction(data1p, data2p, data3p) {
        $(function() {
            data1 = JSON.parse(data1p);
            data2 = JSON.parse(data2p);
            data3 = JSON.parse(data3p);
            //Other different operations            
        });
    }
    //]]>
</script>

我还更改了<p:commandButton>oncomplete 属性的值:oncomplete="createChart(args.data1, args.data2, args.data3);"/> .

请注意,如果需要,可以保留第二个 javascript 函数的旧版本(带有一个args参数(并保留旧版本的 oncomplete 属性。最有力的是第一个将在服务器端调用的javascript函数。

最后,我在 CDI bean 的init()方法中调用了requestcontext.execute()方法,因此我确定将要下载的数据已准备就绪。

    /**
     * Start method.
     */
    @PostConstruct
    public void init() {
        initData();     
        requestContext.execute(String.format("createChart('%s', '%s', '%s')", getProtos(),getData(),getColors()));
    }

execute方法调用第一个 javascript 方法并传递三个必需的值。

请注意,我已经使用了''字符来实现JavaScript端的正确表示。


在客户端

在这种情况下,我只更改了第一个 javascript 函数。我没有使用 args 参数,而是使用了三个参数(每个变量一个(,如上一个示例中所示。我保留了带有 args 参数的第二个函数,但如果需要,可以像前面的示例一样更改它。

最后,我在脚本末尾调用了第一个函数。看看下面的代码。我已经使用 EL 从 CDI bean 传递值。我还删除了JSON.parse()方法,因为EL直接写入javascript代码中,并且浏览器在我的情况下正确解释了数据。

<script type="text/javascript">
    //<![CDATA[
    //Declaration of variables
    var chart;
    var data1;
    var data2;
    var data3;
    function firstFunction(data1p, data2p, data3p) {    
        $(function() {
            data1 = data1p;
            data2 = data2p;
            data3 = data3p;
            //Other operations          
        });
    }
    function secondFunction(args) {
        $(function() {
            data1 = JSON.parse(args.data1);
            data2 = JSON.parse(args.data2);
            data3 = JSON.parse(args.data3);
            //Other different operations            
        });
    }
    firstFunction(#{chart2Controller.data1}, #{chart2Controller.data2}, #{chart2Controller.data3});
    //]]>
</script>

相关内容

  • 没有找到相关文章

最新更新