Как сделать пользовательский компонент JSF для хранения пользовательского типа в качестве значения? - PullRequest
0 голосов
/ 14 января 2019

Кажется достаточно простым ...

У меня есть пользовательский компонент JSF и связанный с ним рендерер. Рендерер делает decode и encodeEnd.

В decode я успешно получил отправленное значение через component.setSubmittedValue(ctx.getExternalContext().getRequestParameterMap().get(c.getClientId()));

В encodeEnd я в основном создаю разметку, и если component.getValue() не равен нулю, я вставляю ее содержимое в разметку. Пока все хорошо.

Проблема в том, что getValue() может быть только String. У меня есть пользовательский класс, который представляет составной тип данных, и я хочу использовать его в качестве локального значения компонента. Но не работает - JSF конвертирует в String.

Я также попытался использовать component.getAttributes() - из метода decode, где я поместил свой пользовательский объект с ключом private static final String someKey = "asd". Но позже на encodeEnd на карте нет значения / ключа.

Я хочу, чтобы пользователи этого компонента могли указывать в своем компоненте пользовательский тип данных и не беспокоиться о сериализации / десериализации в текстовое представление между клиентом / сервером. Предположительно я должен использовать конвертер для этого? Но как мне настроить конвертер по умолчанию и неизменяемый для пользовательского компонента?

1 Ответ

0 голосов
/ 15 января 2019

Проблема имеет достаточно простое решение. Внутри класса Renderer (или прямо в классе Component, если он используется напрямую):

@Override
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
    SomeCustomObject thing;
    //... do magic to create SomeCustomObject based on submittedValue
    return thing;
}

Теперь, когда для этого компонента вызывается getValue(), возвращается SomeCustomObject, и вы можете безопасно привести его к нему. Также в бобах можно использовать SomeCustomObject в качестве типа.

Также обратите внимание, что при вызове component.getValue() в реальном Renderer он также вернет SomeCustomObject, поэтому, если вы восстанавливаете состояние, вы должны преобразовать обратно в его строковое представление.

Для получения более подробной информации см. Ответ @ Kukeltje выше и проверьте, как то же самое делается для компонента календаря простых лиц: https://github.com/primefaces/primefaces/blob/master/src/main/java/org/primefaces/component/calendar/BaseCalendarRenderer.java

Чтобы получить еще более краткую и ясную иллюстрацию, проверьте ответ @ BalusC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...