Как динамически создавать элементы управления формой с помощью DHTML и обрабатывать все эти элементы с помощью JSF? - PullRequest
1 голос
/ 02 июня 2011

Предположим, что это следующая ситуация: создание представления, в котором элементы управления формы отображаются с помощью DHTML (то есть каждый раз, когда пользователь нажимает кнопку, создается новая строка с полями, а идентификаторы полей генерируются и присваиваются полям с тот же DHTML, что и «form1control1» и т. д.), но где эти элементы управления еще не связаны ни с одним UIComponent в ViewRoot (так как они создаются клиентом динамически, и поэтому сервер не знает, что они находятся в форме) Как я могу иметь дело с а) обнаружением этих элементов управления и б) использованием этих имен для проверки и обработки в JSF?

При использовании подхода JSP, который управляет именами и значениями, поставляется с HttpRequest и легко обрабатывать эти элементы, вызывая объект запроса и используя алгоритм, который ищет все объекты с шаблоном, поэтому, где объект с именем ' form1control1 'есть, я найду его с помощью т.е. request.getParameterNames () и request.getParameter ("form" + N + "control" + M), чтобы позже иметь дело с проверкой и преобразованием с использованием кода для всех названных параметров .

Как я понимаю, с JSF мне нужно связать один элемент управления с одним UIComponent, объявив элемент управления в JSP с одним тегом и, следовательно, присоединить любой или оба валидатора или преобразователя к этому элементу управления, чтобы RootView знал элемент управления есть и имеет ассоциированное имя, и он будет ожидать управления этим элементом управления, но мне нужен не элемент управления, объявленный JSP, а элемент, созданный клиентом динамически с помощью JavaScript, позднее отправленный на сервер и обработанный как любой другой элемент, объявленный JSP UIComponent, поэтому я могу перезапустить мой вопрос как: Как мне работать с элементами управления, не объявленными в какой-либо JSP и созданными динамически клиентом с DHTML, для проверки, преобразования и обработки?

Полагаю, я могу сделать это с AJAX, вызывая ViewRoot каждый раз, когда я создаю новую строку с новыми элементами управления, и обновляю ее, добавляя любой элемент управления программно в дерево, но я думаю, что этот подход очень дорогой, так как мне нужен ) сгенерировать запрос AJAX, б) дать работу серверу в любое время, когда я выполняю действие в форме, которая подразумевает использование времени обработки и выделение ресурсов памяти; поэтому, желательно, я бы хотел избежать использования AJAX для обновления ViewRoot с помощью любого нового созданного / удаленного элемента управления. Очевидно, я не закрыт, если обязательно использовать AJAX для обновления ViewRoot для достижения такого поведения. Если я смогу избежать этого последнего подхода, это тоже приветствуется.

Большое спасибо за ваши отзывы заранее.

Ответы [ 2 ]

2 голосов
/ 14 июня 2011

Это возможно, но вам нужно иметь относительно хорошее понимание API JSF, поскольку оно не совсем тривиально. Чтобы сделать это, нужно иметь пользовательский компонент на основе Java в дереве компонентов, который служит контейнером для динамического HTML, который вы будете создавать на клиенте.

С помощью UIComponent#decode или Renderer#decode (если вы используете отдельное средство визуализации) ваш пользовательский компонент Java может проверять запрос после обратной передачи и заполняться необработанными значениями, которые динамически созданные компоненты отправляют на сервер.

Хороший способ понять, как это работает, - просто проверить существующие средства визуализации. Например. упрощенный пример из CheckboxRenderer:

public void decode(FacesContext context, UIComponent component) {

    clientId = component.getClientId(context);

    // Convert the new value
    Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
    boolean isChecked = isChecked(requestParameterMap.get(clientId));
    setSubmittedValue(component, isChecked);
}

private static boolean isChecked(String value) {

    return "on".equalsIgnoreCase(value)
           || "yes".equalsIgnoreCase(value)
           || "true".equalsIgnoreCase(value);

}

Внутри метода декодирования вы обрабатываете все ваши «виртуальные компоненты», и JSF видит все как один компонент.

Также более или менее возможно динамически создавать на стороне сервера представление компонентов, которые были динамически созданы на клиенте. Я говорю более или менее, так как Mojarra (эталонная реализация JSF) в настоящее время имеет некоторые ошибки, которые мешают этому работать во всех ситуациях. Смотрите, например http://java.net/jira/browse/JAVASERVERFACES-1826 Кажется, что MyFaces работает правильно.

Вас может заинтересовать работа, проделанная Ричардом для Metawidget: http://metawidget.org/

Кроме того, я открыл проблему для добавления этого динамического (серверного) компонента в спецификацию JSF. Если вы считаете, что это важно для вашего варианта использования, проголосуйте по этому адресу: http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1007

1 голос
/ 03 июня 2011

Мне неизвестен какой-либо способ создания компонентов на клиенте, которые бы затем автоматически связывались с viewstate при отправке обратно на сервер. Я думаю, вам понадобится Ajax для этого.

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

...