【问题标题】:How to execute javascript function which uses the callback parameters on the server/client side?如何在服务器/客户端执行使用回调参数的javascript函数?
【发布时间】:2016-07-21 19:59:16
【问题描述】:

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

我想实现这样的目标:

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

如您所见,上述机制基于通过RequestContext 将一些值从CDI bean 传递到javascript。为了实现这一点,我基于 primefaces documentation(第 11.1 章)。到目前为止,我已经:

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

目前我的页面是这样的:

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

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

如何调用第一个 javascript 函数?

我尝试了什么?

  • 我尝试在init() 方法中调用服务器端调用requestContext.execute("firstFunction(args)"); 的第一个javascript 函数,希望它能工作,但它不起作用,并且在我使用表单时它会破坏我的表单。我不确定我是否可以像在服务器端那样将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 bean 的一部分:

@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;
}

【问题讨论】:

    标签: javascript jsf primefaces requestcontext


    【解决方案1】:

    我相信把它包装成一个 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          
    
        });
    })();
    

    【讨论】:

    • 感谢您的反馈,但我终于找到了我的问题并修复了它。我还发布了解决方案的答案。
    【解决方案2】:

    我刚刚找到了灵魂。确实有两种解决方案:在服务器端(我推荐)和在客户端。我的问题是这条 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>
    

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

    注意,如果需要,您可以保留旧版本的第二个 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>
    

    【讨论】:

      猜你喜欢
      • 2019-05-22
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2015-01-10
      • 1970-01-01
      相关资源
      最近更新 更多