Жизненный цикл JSF и пользовательские компоненты

StackOverflow https://stackoverflow.com/questions/33476

Вопрос

Есть пара вещей, которые мне трудно понять в связи с разработкой пользовательских компонентов в JSF.Для целей этих вопросов вы можете предположить, что все пользовательские элементы управления используют привязки значений / выражения (не буквальные привязки), но меня также интересуют пояснения к ним.

  1. Где мне установить значение для привязки значения?Должно ли это происходить при декодировании?Или decode должен сделать что-то еще, а затем установить значение в encodeBegin?
  2. Чтение из привязки значения - Когда мне считывать данные из привязки значения по сравнению ссчитывание его из submittedvalue и помещение в valuebinding?
  3. Когда в связи со всем этим вызываются прослушиватели действий в формах?На всех страницах жизненного цикла JSF упоминаются события, происходящие на разных этапах, но мне не совсем понятно, когда вызывается простой прослушиватель commandbutton

Я перепробовал несколько комбинаций, но всегда сталкивался с трудноуловимыми ошибками, которые, как мне кажется, происходят из-за элементарного непонимания жизненного цикла события.

Это было полезно?

Решение

В приложении есть довольно хорошая диаграмма Спецификация JSF это показывает жизненный цикл запроса, что важно для понимания этого материала.

Эти шаги заключаются в следующем:

  • Восстановить вид.Дерево UIComponent перестраивается.
  • Применять Значения запроса.Редактируемые компоненты должны реализовывать EditableValueHolder.На этом этапе выполняется обход дерева компонентов и вызывается Процессдекодирует методы.Если компонент не является чем-то сложным, как UIData, он мало что сделает, кроме как вызовет свой собственный расшифровывать способ.Тот Самый расшифровывать метод мало что делает, кроме как находит свой рендерер и вызывает его расшифровывать метод, передающий себя в качестве аргумента.Задача рендерера - получить любое отправленное значение и установить его с помощью setSubmittedValue - заданное значение.
  • Проверки процесса.Эта фаза требует Процессные валидаторы который вызовет подтвердить.Тот Самый подтвердить метод принимает отправленное значение, преобразует его с помощью любых преобразователей, проверяет его с помощью любых валидаторов и (при условии, что данные проходят эти тесты) вызывает Установленное значение.Это сохранит значение как локальную переменную.Хотя эта локальная переменная не равна null, она будет возвращена, а не значение из привязки value для любых вызовов Получаем значение.
  • Обновление значений модели.Эта фаза требует Процесс обновления.В компоненте ввода это вызовет Обновляемая модель который получит Значение выражения и вызовите его, чтобы установить значение для модели.
  • Вызвать приложение.Здесь будут вызваны прослушиватели событий кнопок и так далее (как и навигация, если память не изменяет).
  • Визуализировать Ответ.Дерево визуализируется с помощью средств визуализации, и состояние сохраняется.
  • Если какой-либо из этих этапов завершится неудачей (например,значение недопустимо), жизненный цикл переходит к отображению ответа.
  • После большинства из этих этапов могут запускаться различные события, вызывающие прослушиватели по мере необходимости (например, прослушиватели изменения значения после проверки процесса).

Это несколько упрощенная версия событий.Обратитесь к спецификации для получения более подробной информации.

Я бы задался вопросом, почему вы пишете свой собственный UIComponent.Это нетривиальная задача, и для ее решения требуется глубокое понимание архитектуры JSF.Если вам нужен пользовательский элемент управления, лучше создать конкретный элемент управления, который расширяет существующий UIComponent (как это делает HtmlInputText) с помощью эквивалентного средства визуализации.

Если загрязнение не является проблемой, существует реализация JSF с открытым исходным кодом в виде Apache MyFaces.

Другие советы

Прослушиватели действий, например, для Командная кнопка, вызываются во время Вызвать приложение фаза, которая является последней фазой перед финальным Визуализировать Ответ фаза.Это показано в Жизненный цикл JSF - рисунок 1.

Это единственный фреймворк, который я когда-либо использовал, где создание компонентов - это глубокий сложный процесс, подобный этому.Ни один из других веб-фреймворков (будь то в мире .net или нет) не делает это настолько болезненным, что для меня совершенно необъяснимо.

Некоторые дизайнерские решения, лежащие в основе JSF, начинают приобретать немного больше смысла, если учесть поставленные цели.JSF был разработан для работы с инструментами - он предоставляет множество метаданных для IDE.JSF - это не веб-фреймворк, это MVP фреймворк, который может быть использован в качестве веб-фреймворка.JSF обладает высокой степенью расширения и конфигурирования - вы можете заменить 90% реализации для каждого приложения.

Большая часть этого материала просто усложняет вашу работу, если все, что вы хотите сделать, это вставить дополнительный HTML-элемент управления.

Компонент представляет собой композицию из нескольких базовых компонентов inputtext (и других) , кстати.

Я предполагаю, что фрагменты страницы на основе JSP-includes / tooling не соответствуют вашим требованиям.

Я бы подумал о том, чтобы использовать ваш UIComponentELTag.Создать компонент создать составной элемент управления с базой UIPanel и создать все его дочерние элементы из существующих реализаций.(Я предполагаю, что вы используете JSP / taglibs и делаете несколько других предположений.) Вероятно, вам понадобился бы пользовательский рендерер, если бы ни один из существующих рендереров UIPanel не выполнял эту работу, но рендереры просты.

Лучшая статья, которую я нашел, это Написание компонента Jsf, что касается 2, где я могу прочитать значение для привязки значения в вашем компоненте, у вас есть геттер, который выглядит следующим образом


public String getBar() {  
     if (null != this.bar) {  
         return this.bar ;  
     }  
     ValueBinding _vb = getValueBinding("bar");  
     return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;  
}
  

как это попало в getValueBinding?В вашем классе тегов setProperties метод

  if (bar!= null) {  
         if (isValueReference(bar)) {  
             ValueBinding vb = Util.getValueBinding(bar);  
             foo.setValueBinding("bar", vb);  
         } else {  
             throw new IllegalStateException("The value for 'bar' must be a ValueBinding.");  
         }  
     }  
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top