Привязка компонентов против 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). Я отправил ответ там.

Другие вопросы по тегам