адресация компонентов из других именующих контейнеров - PullRequest
2 голосов
/ 16 ноября 2011

Чего я хотел бы добиться, так это иметь возможность обращаться к некоторым компонентам JSF из другого контейнера именования.

Usecase: составной компонент, который инкапсулирует некоторые функции, используя - для поля, определенного вне составного компонента.

Какой-то код:

<form id="foo">
...
<label for="nameTxt">Name:</label>
<component:customError forField="nameTxt" />
<h:inputText id="nameTxt" />
...
</form>

и компонент:

<composite:implementation>
    <h:panelGroup id="errorComponent">
    ...
    <h:message for="#{cc.attrs.forField}" id="errorMsg" style="display:none;" />
    ...
    </h:panelGroup>
</composite:implementation>

Проблема в том, что при рендеринге сообщения я получаю:

Could not render Message. Unable to find component 'nameTxt' (calling findComponent on component 'j_id963445801_469fc056:errorMsg')

Мне кажется, я понимаю, что проблема заключается в том, что поле "nameTxt" и сообщение "errorMsg" лежат в других контейнерах имен. Поэтому я хотел бы указать путь / идентификатор "nameTxt" по отношению к некоторому общему предку.

После краткого изучения алгоритма UIComponentBase: findComponent На самом деле я не вижу другого способа адресации кросс-контейнеров именования, кроме указания целого (абсолютного) id-пути из корня (то есть ": foo: ...: nameTxt "). И это неуклюже и может привести к ошибкам после изменения структуры страницы.

Итак - как правильно обратиться к полю "nameTxt" из сообщения в составном компоненте?

1 Ответ

1 голос
/ 16 ноября 2011

Я могу воспроизвести вашу проблему на MyFaces 2.1.3, но не на Mojarra 2.1.4 (а также на более старой Mojarra 2.0.2).Вероятно, это ошибка в MyFaces, вам нужно сообщить об этом парням MyFaces .Между тем, я не вижу никакой другой возможности, кроме (временно) замены реализации JSF Моджаррой.Однако он также имеет свою долю проблем, в основном из-за неправильных реализаций <ui:repeat> и частичного сохранения состояния.


Обновление: Я нашел обходной путь, однако он немногоclumsy:

<component:customError forField=":#{nameTxt.clientId}" />
<h:inputText id="nameTxt" binding="#{nameTxt}" />

При поиске будет использоваться абсолютный идентификатор клиента вместо относительного идентификатора клиента.Вам нужно всего лишь удалить style="display:none" из вашего <h:message>, чтобы решить другой вопрос.

...