UIForm с prependId = «false» breaks

У меня есть вопрос по поводу идеи, лежащей в основе того факта, что только 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 () .

Что вы думаете об этом и почему, черт возьми, это реализовано именно так? Я не могу быть первым, у кого возникла эта проблема, но мне не удалось найти связанные темы ?!

20
задан BalusC 28 October 2015 в 13:35
поделиться