У меня возник вопрос о том, что только тот факт, что только UIForm
получил атрибут prependId
. Почему атрибут не указан в интерфейсе NamingContainer
? Теперь вы, вероятно, скажете, что из-за обратной совместимости, но я бы предпочел бы нарушить компиляцию и позволить пользователям, которые реализуют этот интерфейс, также реализовать методы для prependId.
Основная проблема с моей точки зрения относительно prependId в компоненте UIForm
заключается в том, что она сломается findComponent()
Я ожидал бы, что если я использую prependId
, тогда поведение NamingContainer
изменилось бы, не только относящееся к рендерингу, но также и при поиске компонентов в дереве компонентов.
Вот простой пример:
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
Теперь, когда я хочу получить компонент panelGroup, я ожидал бы передать строку "group"
методу findComponent()
, но он ничего не найдет, вместо этого я должен использовать "test:group"
.
Конкретная проблема с этим заключается в использовании ajax с prependId="false"
. Тег ajax ожидает в обновлении и обработке атрибутов, что ценности заботятся об именовании контейнеров. Немного странно, что, когда я использую prependId="false"
, я должен указать полный идентификатор или путь, но хорошо.
<h:form id="test" prependId="false">
<h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
<h:commandButton value="go">
<f:ajax render="test:group"/>
</h:commandButton>
</h:form>
Ну, этот код будет отображаться без проблем, но он не будет обновлять panelGroup, потому что он не может его найти. PartialViewContext
будет содержать только id "group"
как элемент renderIds. Я не знаю, ожидалось ли это, возможно, но я не знаю кода. Теперь мы переходим к точке, где метод findComponent()
не может найти компонент, потому что выражение, переданное как параметр, "group"
, где метод ожидает, что "test:group"
найдет компонент.
Одним из решений является написать собственный findComponent()
, который я выбрал для решения этой проблемы. В этом методе я обрабатываю компонент, который является NamingContainer
и имеет свойство prependId, установленное как false, как обычный UIComponent
. Мне нужно будет сделать это для каждого UIComponent
, который предлагает атрибут prependId, и это плохо. Отражение поможет обойти статическое определение типов, но это еще не очень чистое решение.
Другой способ - ввести атрибут prependId в интерфейсе NamingContainer
и изменить поведение findComponent()
для работы, как описано выше.
Последнее предлагаемое решение изменило бы поведение тега ajax, чтобы передать весь идентификатор, но это разрешило бы только проблему ajax, а не программные проблемы реализации findComponent()
.
Что вы думаете об этом и почему, черт возьми, это реализовано так? Я не могу быть первым с этой проблемой, но мне не удалось найти связанные темы?!