Я считаю, что большинство разработчиков ADF знают атрибут ADF Faces clientComponent . В этом посте я собираюсь показать, как этот атрибут влияет на рендеринг компонентов и как он может изменить их поведение. Давайте начнем с рассмотрения очень простого примера:
1
2
|
<af:inputText label= "Label 1" id= "it1" /> <af:outputText value= "outputText1" id= "ot1" /> |
Страница результатов выглядит следующим образом:
И давайте посмотрим на сгенерированный HTML:
Мы можем видеть, что наш outputText был превращен в простую текстовую строку. Там нет никакого компонента, представляющего его. Выражение Java Script AdfPage.PAGE.findComponent («ot1») вернет «неопределенное» . Даже выражение document.getElementById («ot1») будет возвращать ноль . Таким образом, у нас нет ни расширенного объекта ADS Faces JS, ни собственного элемента DOM, соответствующего нашему outputText . Вообще ничего
Давайте сделаем наш пример немного сложнее:
1
2
3
4
5
|
<af:inputText label= "Label 1" id= "it1" autoSubmit= "true" value= "#{MainTest.someValue}" valueChangeListener= "#{MainTest.inputTextListener}" /> <af:outputText value= "#{MainTest.someValue}" id= "ot1" binding= "#{MainTest.outputText}" /> |
InputText хранит свое значение в управляемом компоненте, и это значение должно быть отображено в outputText . Значение valueChangeListener для inputText добавляет outputText в контекст граней как частичную цель:
1
2
3
4
|
public void inputTextListener(ValueChangeEvent valueChangeEvent) { AdfFacesContext ctx = AdfFacesContext.getCurrentInstance(); ctx.addPartialTarget(outputText); } |
Кажется, все в порядке, но это не работает. Кроме того, мы найдем следующее сообщение в журнале:
1
|
<PprResponseWriter$PPRTag> <finish> no PPR-capable ID found for elements of: RichOutputText[UIXFacesBeanImpl, id =ot1] |
Это из-за отсутствия соответствующего компонента на стороне клиента. Выходной текст представлен простым текстом.
Хорошо, давайте установим для clientComponent outputText значение true:
1
2
3
|
<af:outputText value= "#{MainTest.someValue}" id= "ot1" binding= "#{MainTest.outputText}" clientComponent= "true" /> |
И наш пример работает !
Посмотрите на HTML:
Существует обработанный тег HTML, представляющий наш outputText. Выражение Java Script document.getElementById («ot1») возвращает HTMLSpanElement. А выражение AdfPage.PAGE.findComponent («ot1») возвращает AdfRichOutputText , представляющий собой объект JS ADF Faces, созданный с помощью следующего кода JS:
Хорошо, давайте сделаем outputText зависимым от inputText с точки зрения частичного рендеринга:
1
2
3
|
<af:inputText label= "Label 1" id= "it1" autoSubmit= "true" value= "#{MainTest.someValue}" /> <af:outputText value= "#{MainTest.someValue}" id= "ot1" partialTriggers= "it1" /> |
Этот пример проще, чем предыдущий, и он работает. Выражение JS document.getElementById («ot1») возвращает HTMLSpanElement, однако выражение AdfPage.PAGE.findComponent («ot1») возвращает «undefined» . Не существует созданного объекта клиента ADF Faces для outputText, но элемент DOM ( span ) визуализирован.
Фактически, атрибут clientComponent обычно используется для получения объекта JS ADF Faces, созданного на стороне клиента. Но, кроме того, атрибут clientComponent вызывает рендеринг элемента DOM для компонента, и иногда нам может понадобиться использовать атрибут clientComponent только по этой причине. Мы сделали это в первом примере и получили его работать.