2016-07-21 11 views
1

私はJSF 2.2、Primefaces 6.0とCDIを使用します。私のページの1つは、2つのjavascript関数(そのうちの1つはチャートを作成し、2つ目はチャートに新しいデータを提供する)とフィルタとして機能する単純なフォームを持つスクリプトを含みます。私は自分のコードの中で最も重要な部分を示すためにコードをカットしました(下を見てください)。サーバー/クライアント側でコールバックパラメータを使用するjavascript関数の実行方法は?

私はこのような何かを達成したいと思います:ページが開か/ロードされて初めて

  • を、最初のJavaScript関数は、(任意のボタンやリンクを押さなくても自動的に)実行する必要がありますとすべき私がcdi beanで設定したいくつかのコールバックパラメータを使用します。
  • ボタンを押すたびに、2番目のjavascript関数が実行され、CDI Beanで設定したいくつかのコールバックパラメータを使用する必要があります。

上記のメカニズムは、RequestContextを使用してCDI Beanの一部の値をJavaScriptに渡すことに基づいています。これを実現するために、素形documentation(11.1章)に基づいています。これまでのところ、私がしました:

  • はCDI Beanの(@PostConstruct注釈を持っている)init()メソッドの最初の関数のためのいくつかのコールバックパラメータを作成しました。
  • は、argsパラメータで2番目の関数を呼び出す<p:commandButton>コンポーネントにoncomplete属性を追加しました。 2番目の関数に渡したい値は、ボタンのaction属性で呼び出すactionFilterButton()メソッドで用意されています。

瞬間に私のページには、次のように機能します。

  • ページが開か/ロードされると、最初のJavaScript関数が実行されていません。
  • ボタンを押すと、2番目のjavascript関数が実行され、コールバックパラメータの値がjavascript変数に保存されます。

どのように見えますか、問題は最初の段階です。私のページを開くと、最初のjavascript関数は実行されません。

最初のjavascript関数をどのように呼び出すことができますか?

私は何を試しましたか?

  • 私はそれが働いていたことでしょうが、それは動作していないと私はフォームを使用する場合、それは私のフォームを壊すの希望でinit()方法でrequestContext.execute("firstFunction(args)");を呼び出して、サーバー側の第1の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; 
} 

答えて

0

私は魂を見つけました。確かに2つのソリューション:サーバー側(お勧め)とクライアント側。私の問題は、このjavascriptの行だった:firstFunction(args);argsパラメータが正しく解釈されませんでした。サーバー側では


は、すべての

最初に私は私のjavascriptの関数のパラメータを変更しました。 argsパラメータの代わりに、3つのパラメータ(各変数に1つ)を使用しました。現時点では、スクリプトは次のようになります。

<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);"/>。あなたがしたい場合、あなたは(1つのargsパラメータを持つ)は、第2のjavascript関数の古いバージョンを保持し、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メソッドを呼び出して、3つの必須の値を渡します。

なお

は、私はjavascriptの側に正しい表現を実現するために''文字を使用しました。この場合、クライアント側


、私は最初のJavaScript関数を変更しました。 argsパラメータの代わりに、前の例のように3つのパラメータ(各変数に1つ)を使用しました。私はargsパラメータで2番目の関数を保持していますが、必要に応じて前の例と同様に変更できます。

最後に、スクリプトの最後に最初の関数を呼び出しました。下のコードを見てください。 ELを使用してCDI Beanの値を渡しました。 ELはjavascriptコードに直接書き込まれており、ブラウザが私のケースでデータを正しく解釈したので、私はJSON.parse()メソッドも削除しました。

<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> 

1

私は生命維持としてそれをラップすることはトリックを行うだろうと信じています。あまりにも速く読み込んでdomが必要な場合は、on loadのようなものを試してみてください。

(function firstFunction(args) { 

    $(function() { 

     data1 = JSON.parse(args.data1); 
     data2 = JSON.parse(args.data2); 
     data3 = JSON.parse(args.data3); 

     //Other operations   

    }); 
})(); 
+0

ご意見ありがとうございますが、最終的に私の問題が見つかりました。修正しました。私はまた、ソリューションの回答を掲載しました。 – Robert

関連する問題