Событие PostAddToView не запущено для Head в myfaces - PullRequest
1 голос
/ 10 апреля 2020

Я динамически внедряю некоторые JS во все мои страницы, и это хорошо работает в Мохарре, но я обнаружил, что это не удается в моих лицах.

Мой слушатель событий настроен как:

<application>
    <system-event-listener>
        <system-event-listener-class>a.b.HeadResourceListener</system-event-listener-class>
        <system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
        <source-class>javax.faces.component.UIOutput</source-class>
    </system-event-listener>
</application>

С кодом, похожим на:

public class HeadResourceListener implements SystemEventListener {

  @Override
  public boolean isListenerForSource(Object source) {
    return "javax.faces.Head".equals(((UIComponent) source).getRendererType());
  }

  @Override
  public void processEvent(SystemEvent event) {
    UIComponent outputScript = new UIOutput();
    outputScript.setRendererType("javax.faces.resource.Script");
    UIOutput content = new UIOutput();
    content.setValue("var abc='';");
    outputScript.getChildren().add(content);
    context.getViewRoot().addComponentResource(context, outputScript, "head");
  }
}

К сожалению, с myfaces rendererType источника никогда не будет javax.faces.Head (я только нашел вхождения javax.faces.resources .Script и javax.faces.resources.Stylesheet)

Существует ли какая-либо конкретная c причина, по которой поведение здесь отличается? Может быть, есть какие-нибудь предложения для другого решения?

РЕДАКТИРОВАТЬ

Как и предполагалось, при привязке этого слушателя к исходному классу он запускается в myfaces. Однако при обратной передаче я получаю повторяющиеся ошибки идентификатора ...

Caused by: org.apache.myfaces.view.facelets.compiler.DuplicateIdException:    Component with duplicate id "j_id__v_7" found. The first component is {Component-  Path : [Class: javax.faces.component.UIViewRoot,ViewId: /user/login.xhtml][Class:  org.apache.myfaces.component.ComponentResourceContainer,Id:  javax_faces_location_head][Class: javax.faces.component.UIOutput,Id: j_id__v_7]}
at  org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.createAndQueueException(CheckDuplicateIdFaceletUtils.java:148)
at [internal classes]
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)
at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:169)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:73)

1 Ответ

2 голосов
/ 17 апреля 2020

Это ошибка в MyFaces.

Спецификация JSF 2.3 говорит следующее в таблице 9.2:

ТАБЛИЦА 9-2 Стандартная HTML Библиотека тегов RenderKit

getComponentType()     getRendererType()
javax.faces.Output     javax.faces.Head

Согласно главе 4.1.10.1 той же спецификации, javax.faces.Output отображается на javax.faces.component.UIOutput.

4.1.10.1 Тип компонента

Стандартный тип компонента для UIOutput компонентов - «javax.faces.Output».

Таким образом, <h:head> должен быть экземпляром из UIOutput.

Если мы посмотрим на таблицу 9.2, javax.faces.Output может иметь несколько средств визуализации, так что вы действительно можете прослушивать только <source-class> из javax.faces.component.UIOutput, и вам придется проверять вручную его тип рендерера будет javax.faces.Head. Ваш HeadResourceListener правильный.

См. Также:

...