Привязка компонентов против findComponent() - когда и какие использовать?
Как описано в этом вопросе, я пытаюсь выполнить некоторую проверку полей в форме на стороне поддерживающего компонента. Для этого я хотел бы получить доступ к нарушающим полям, чтобы пометить их. Похоже, что при поиске в Интернете есть два способа сделать это:
- сохранить компоненты в компоненте для доступа и использовать их на страницах JSF через
binding
приписывать. - Используйте стандартное связывание значений на страницах JSF, и когда вам нужен доступ к компоненту из компонента, ищите его через
UIViewRoot.findComponent(String id)
Насколько я вижу, оба способа имеют свои недостатки: привязки компонентов взрывают базовый компонент с помощью переменных и методов получения / установки, некоторые сайты категорически не рекомендуют использовать привязку компонентов вообще. В любом случае, объем запроса рекомендуется. С другой стороны, findComponent() всегда пересекает дерево, которое может быть или не быть дорогостоящим, верно? (Плюс, на данный момент я не могу найти свой компонент вообще, но это другая проблема)
Какой путь будет идти? Являются ли эти взаимозаменяемые альтернативы, а если нет, то по каким критериям вы выбрали? В настоящее время мне просто не хватает понимания, чтобы принять достойное решение...
1 ответ
Прежде всего, независимо от выбора, оба являются плохой практикой. Смотрите также Как работает атрибут 'binding' в JSF? Когда и как его следует использовать?
Если вам пришлось сделать выбор, привязки компонентов, безусловно, быстрее и дешевле. Логически совершенно логично, что сканирование дерева выполняется UIComponent#findComponent()
имеет свои последствия для производительности.
Действительно, компонент поддержки, содержащий привязки компонентов, должен иметь область запроса, но вы можете легко внедрить компонент поддержки, содержащий бизнес-логику, с помощью @ManagedProperty
,
Более чистым подходом будет использование Map
как держатель всех компонентных привязок. Вам нужно только добавить следующую запись в faces-config.xml
:
<managed-bean>
<managed-bean-name>components</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Это можно просто использовать как
<h:inputSome binding="#{components.input1}" />
<h:inputSome binding="#{components.input2}" />
<h:inputSome binding="#{components.input3}" />
И это может быть получено в других бобах как
Map<String, UIComponent> components = (Map<String, UIComponent>) externalContext.getRequestMap().get("components");
Таким образом, вам не нужно беспокоиться об указании отдельных свойств / методов получения / установки. В приведенном выше примере Map
будет содержать три записи с ключами input1
, input2
а также input3
каждый с соответствующим UIComponent
экземпляр как значение.
Не связанный с конкретным вопросом, может быть гораздо более простое решение конкретной проблемы, как вы описали в другом вопросе, чем выполнение проверки в методе действия (который на самом деле является Bad Design). Я отправил ответ там.