2016-04-10 12 views
1

を追加するために豆からコマンドボタンを:アクセスPrimeFacesは、私はID「保存」を持つビューで次のコマンドボタンを持つアクションリスナー

 <p:panel style="border:none;text-align:left;margin:0;"> 

      <p:commandButton value="Save Document" id="save" icon="fa fa-save" 
       disabled="#{dIGRCController.digrc.qconce == '020'}"> 

       <f:param name="validate" value="true" /> 

      </p:commandButton> 

      <p:commandButton value="Clear" icon="fa fa-undo"></p:commandButton> 

     </p:panel> 

私は動的に異なるActionListenerを割り当てるしようとしています。ユーザーが新しいレコードをいくつか挿入したい場合は、insertメソッドを呼び出す必要があります。ユーザーが既存のレコードを更新したい場合は、updateメソッドを呼び出す必要があります。

は今、私はこれを行うにしようとしています:

@PostConstruct 
public void init() { 

    // setting the action listener of the Save Document button 
    UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot(); 

    // UIComponent button = viewRoot.findComponent("save"); 

    CommandButton button = (CommandButton) viewRoot.findComponent("save"); 

    FacesContext context = FacesContext.getCurrentInstance(); 

    MethodExpression methodExpression = context 
      .getApplication() 
      .getExpressionFactory() 
      .createMethodExpression(context.getELContext(), 
        "#{dIGRCController.updateDocument}", null, 
        new Class[] { DIGRCController.class }); 

    button.addActionListener(new MethodExpressionActionListener(
      methodExpression)); 

} 

私はライン上でnullポインタ例外を取得しています:

button.addActionListener(new MethodExpressionActionListener(
     methodExpression)); 

私が間違っているのか?私がしようとしていることを達成する別の方法がありますか?私はJSF 2.2、PrimeFaces 5.3、OmniFaces 1.11を使用しています。

+1

'findComponent()'はコンポーネントIDではなく、引数としてクライアントIDをとります。しかし、これはすべて複雑すぎるように見えます。ビューの定義は通常、JavaクラスではなくXHTMLファイルで行われます。 Java側でコンポーネントツリーを操作することは貧しい方法です。そのためにはJSTLを使うほうが良いでしょう。つまり、Javaコードよりもコンポーネント/属性を定義するほど自己記述性の高いXHTMLを使い続けることができます。 – BalusC

+0

入手しました。私はまた、2つのコマンドボタンを持つことを考えていた:更新ともう一つの挿入。そして、あるものには更新のための条件が与えられ、もうひとつには挿入条件が与えられる。そのデザイン@BalusCについてどう思いますか? – Erick

+0

条件がどこから来るかによって異なりますが、それは確かに一方向です。条件がビューのビルド時間に基づいている場合は、基本的にJavaコードの試行と同じように、 ' 'という単一のコマンドボタンを使用できます。 – BalusC

答えて

1

findComponent()は、コンポーネントIDではなくクライアントIDを引数として取ります。クライアントIDは、生成されたHTML id属性の値とまったく同じです。コマンドボタンの場合、通常、親のコンポーネントIDは<h:form>となり、デフォルトの:という命名コンテナの区切り文字で区切られます。このことを考えると

<h:form id="form"> 
    <p:commandButton id="save" ... /> 
</h:form> 

クライアントIDはform:saveだろう。

CommandButton button = (CommandButton) viewRoot.findComponent("form:save"); 

参照識別し、クライアントのIDを使用するようにも、この関連の質問:How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"


無関係具体的な問題に、Java側でコンポーネントツリーを操作することが悪い習慣です。このためにXHTML + XMLを使い続ける方が良いでしょう。これは、ツリー構造の宣言/定義に関して、はるかに自己文書化しています。 JSTLタグを使用してビューを動的に構築することができます(注:rendered属性を使用してビューを動的にレンダリングするのとは異なります)。

など。

<p:commandButton ... action="#{bean.save}"> 
    <c:if test="#{bean.existing}"> 
     <f:actionListener binding="#{bean.needsUpdate()}" /> 
    </c:if> 
</p:commandButton> 

はさらに、あなただけのメソッドの引数として#{bean.existing}を渡すことができ、またJSTL in JSF2 Facelets... makes sense?

参照してください。 #{bean.existing}#{bean.save}同じBeanを参照する場合

<p:commandButton ... action="#{bean.save(bean.existing)}" /> 

両方のアプローチは、今度は確か種類の奇妙です。 #{bean.save}の内部でそれを確認することができます。

public void save() { 
    if (existing) { 
     // UPDATE 
    } else { 
     // INSERT 
    } 
} 

さらに、これは、フロントエンド層の責任ではなく、サービス層のIMOです。エンティティ全体をサービスレイヤに渡します。エンティティ全体がPKに基づいて既存のものかどうかを確認します。

if (entity.getId() == null) { 
    // INSERT 
} else { 
    // UPDATE 
} 
+0

驚くばかり!私はその解決策が大好きです。私は2つのボタンを作成してレンダリングについて言ったよりもはるかに優れています!ありがとう@BalusC! – Erick

+0

ようこそ。 – BalusC

関連する問題