web-dev-qa-db-ja.com

JSF 2.0 AJAX:jsf.ajax.request(または他の方法)を使用してjavascriptからbeanメソッドを呼び出します

背景:カスタムJSFコンポーネントを構築しています。コンポーネントは基本的にテキストエディタであり、エディタのコンテンツ文字列を保存するための「保存」ボタンが必要です。 CodeMirror ライブラリを使用しているので、JavaScriptを使用してエディターからコンテンツ(文字列)をフェッチし、サーバーに送信する必要があります。したがって、この場合、f:ajaxなどのXMLベースのJS呼び出しを使用することはできません。

質問:文字列をjsf.ajax.requestで送信することを計画していましたが、Beanでのメソッドの呼び出しを直接サポートしていません。 AJAXの方法でJSFを使用してBeanのメソッドを呼び出すにはどうすればよいですか?

これを回避するには、少なくとも2つの方法があります。

  • 非表示の入力フィールドを持つページに非表示のフォームを含めます。その入力フィールドをjavascriptから更新してから、jsf.ajax.requestを呼び出してそのフォームを投稿します。カスタムアクションは、必要に応じてプロパティのゲッターまたはセッターで呼び出すことができます。
  • Raw XMLHttpRequestを使用して(または他のJSライブラリの助けを借りて)リクエストを実行します。サーブレットを作成して呼び出します。

どちらの方法も不器用で、後者もJSFの範囲から外れます。

私は何かが足りないのですか?これらをどのように行いますか?

非常によく似た質問 がありますが、与えられた答えはXMLベースのAJAX呼び出しのみを参照しています。 別の同様の質問 、しかし、それはXMLベースのAJAX呼び出しも参照します。

13
Tuukka Mustonen

Javascriptを使用してBeanを直接呼び出す方法を見つけることができませんでしたが、javascriptからf:ajax-declarationを呼び出す方法をハックします。

1)サーバーに送信するすべてのデータのフィールドを含む非表示のフォームを作成します。 h:commandButtonも含めます。

_<h:form id="hiddenForm" style="display: none;">
    <h:inputHidden id="someData" value="#{someBean.someData}" />
    <h:commandButton id="invisibleClickTarget">
        <f:ajax execute="@form" listener="#{someBean.myCoolActionOnServer()}" />
    </h:commandButton>
</h:form>
_

いつものように、listener属性、この場合は#{someBean.myCoolActionOnServer()}は、サーバーで実行するメソッドを参照します。

2)他のボタンでは、onclickを使用して特別なJavaScriptを呼び出し、JavaScriptを介してトリガーボタンをクリックします。

_<h:commandButton value="Click me" onclick="populateTheForm('hiddenForm'); document.getElementById('hiddenForm:invisibleClickTarget').click(); return false;" />
_

populateTheForm()は、実際にはhiddenFormのフィールドにデータを入力する必要があります。

これは私の場合を単純化したものですが、機能するはずです。ただし、さらに便利なアプローチを探しています。

15
Tuukka Mustonen

私はこの仕事を数回しました。隠されたフィールドを増やす必要はありません。非表示フィールドは1つだけ使用でき、すべての入力値をJSON.stringifyを介してJSONオブジェクトに変換し、このフィールドに設定できます。サーバー側では、JSONオブジェクト(そのための多くのJavaライブラリがあります)をJavaクラスにデシリアライズします。これですべてです。

1
Oleg