JSF 2.0 AJAX: вызов метода bean из javascript с помощью jsf.ajax.request(или каким-либо другим способом)

Некоторые предпосылки: я создаю настраиваемый компонент JSF. Компонент в основном представляет собой текстовый редактор, и он должен иметь кнопку "Сохранить" для сохранения строки содержимого редактора. Поскольку я использую библиотеку CodeMirror, мне нужно получить содержимое (строку) из редактора с помощью javascript и отправить его на сервер, Поэтому в этом случае я не могу использовать JS-вызов на основе XML, такой как f:ajax.

Вопрос: я планировал отправить строку с помощью jsf.ajax.request, но она напрямую не поддерживает методы вызова на beans. Как я могу вызвать метод в bean с JSF в AJAX образом?

Есть как минимум два способа обойти это:

  • Включите скрытую форму на страницу со скрытым полем ввода. Обновите это поле ввода из javascript, а затем вызовите jsf.ajax.request, чтобы опубликовать эту форму. Пользовательские действия могут быть введены в свойство getter или setter при необходимости.
  • Сделайте запрос с raw XMLHttpRequest (или, может быть, с помощью другой JS-библиотеки). Создайте сервлет и вызовите его.

Оба способа неуклюжи, а последний также выходит из сферы действия JSF.

Я что-то упустил? Как вы это делаете?

Существует довольно похожий вопрос, но ответы даны только для ссылок на XML-AJAX-вызовы. Существует также другой аналогичный вопрос, но это также относится к вызовам AJAX на основе XML.

Ответ 1

Я не мог узнать, как вызвать beans с javascript, но вот взломать вызов f: ajax-declation из javascript:

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.

Это упрощение моего дела, но оно должно работать. Тем не менее, поиск более удобного подхода.

Ответ 2

Я выполнял эту задачу несколько раз. Йо не нужно многократно скрывать. Вы можете использовать только одно скрытое поле, преобразовать все входные значения в объект JSON через JSON.stringify и установить в это поле. На стороне сервера - десериализовать объект JSON (для него много Java-библиотек) для класса Java. Это все.