JSF postAddToView не добавляет компонент в дерево компонентов - PullRequest
0 голосов
/ 30 мая 2019

Использование postAddToView, как BalusC написал в по этой ссылке , работает как положено. Я создаю компонент программным способом, добавляю к нему поведение ajax, компонент добавляется в дерево компонентов, добавляется идентификатор (например, если я пишу setId("uniqueId"), я вижу на стороне клиента, что все родительские контейнеры именования добавляются - я получаю form:uniqueId). Слушатель Ajax вызывается, и все обновляется, как и ожидалось.

Однако, если я повторяю то же самое, но на этот раз внутри таблицы данных PrimeFaces, выполняется рендеринг HTML, выполняется рендеринг JavaScript PrimeFaces, все остается таким же , за исключением , ни один из программно созданных компонентов не добавляется в дерево компонентов, и сгенерированный идентификатор клиента не добавляется (это не form:uniqueId, а просто uniqueId.

Есть идеи, как это решить? JSF 2.2 MyFaces, PrimeFaces 7.0, Omnifaces 2.7 WebSphere Liberty EE7.

<ui:composition template="WEB-INF/templates/main.xhtml">
    <ui:define name="content">
        <h:form id="form">
            <p:dataTable id="table">
                <f:event type="postAddToView" listener="#{myBean.populateDatatable}" />
                <p:column>
                    <p:inputText value="#{myBean.testField}">
                    </p:inputText>
                </p:column>
            </p:dataTable>
        </h:form>

        <h:form id="form2">
            <f:event type="postAddToView" listener="#{myBean.populateForm}" />
        </h:form>

    </ui:define>
</ui:composition>

Bean:

public void test()  {
    log.debug("Ajax listener is called!");
}
/* This is working fine! */
public void populateForm(ComponentSystemEvent event) {

    FacesContext fc = FacesContext.getCurrentInstance();
    Application application = fc.getApplication();
    ExpressionFactory ef = application.getExpressionFactory();
    ELContext elc = fc.getELContext();

    HtmlForm form = (HtmlForm) event.getComponent();
    UIInput input = new HtmlInputText();
    input.setId("testInput"); // Must be unique!
    ValueExpression valueExp = ef.createValueExpression(elc, "#{myBean.testField}", Object.class);
    input.setValueExpression("value", valueExp);

    AjaxBehavior ajax = (AjaxBehavior)application.createBehavior(AjaxBehavior.BEHAVIOR_ID);
    ajax.setGlobal(false);
    ajax.setProcess("@this");
    ajax.setPartialSubmit(true);
    ajax.setUpdate("@this");
    ajax.setForm("form");
    ajax.setListener(ef.createMethodExpression(elc, "#{myBean.test}", null, new Class[] {}));
    input.addClientBehavior("change", ajax);

    form.getChildren().add(input);
}
/* This is NOT working fine! */
public void populateDatatable(ComponentSystemEvent event) {

    DataTable table = (DataTable) event.getComponent();

    List<UIColumn> columns = new ArrayList<>();

    UIComponentBase[] datatableComponentRow1 = new UIComponentBase[someList.size()];

    FacesContext fc = FacesContext.getCurrentInstance();
    Application application = fc.getApplication();
    ExpressionFactory ef = application.getExpressionFactory();
    ELContext elc = fc.getELContext();

    for (int i = 0; i < someList.size(); i++) {

        HtmlOutputText text = (HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        text.setValue(someList.get(i).getSomeField());
        text.setId("out_" + i);

        InputText inputText = (InputText)application.createComponent(InputText.COMPONENT_TYPE);
        inputText.setId("input_" + i);
        ValueExpression valueExp = ef.createValueExpression(elc, "#{myBean.someList[" + i + "].someInputFieldFromThatList}", Object.class);
        inputText.setValueExpression("value", valueExp);
        AjaxBehavior ajax = (AjaxBehavior)application.createBehavior(AjaxBehavior.BEHAVIOR_ID);
        ajax.setGlobal(false);
        ajax.setProcess("@this");
        ajax.setPartialSubmit(true);
        ajax.setUpdate("@this");
        ajax.setForm("form");
        ajax.setListener(ef.createMethodExpression(elc, "#{myBean.test}", null, new Class[] {}));
        inputText.addClientBehavior("change", ajax);

        HtmlPanelGrid panelGrid = (HtmlPanelGrid)application.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
        panelGrid.setId("grid_" + i);
        panelGrid.getChildren().add(text);
        panelGrid.getChildren().add(inputText);

        Column column = (Column)application.createComponent(Column.COMPONENT_TYPE);
        column.setId("col_" + i);
        column.setHeaderText(someList.get(i).getSomeFieldFromThatListForColumnHeader());
        column.getChildren().add(panelGrid);

        columns.add(column);

    }

    List<UIComponentBase[]> mockListSoWeGetOneRowInDatatable = new ArrayList<>();
    mockListSoWeGetOneRowInDatatable.add(uiComponentsArrayOfSameLengthAsNumberOfColumns);

/* This is ALSO working fine - that single p:column in XHTML file - here i add ajax behaviour to it's inputText programmaticaly*/
    AjaxBehavior ajax = (AjaxBehavior)application.createBehavior(AjaxBehavior.BEHAVIOR_ID);
    ajax.setGlobal(false);
    ajax.setProcess("@this");
    ajax.setPartialSubmit(true);
    ajax.setUpdate("@this");
    ajax.setForm("form");
    ajax.setListener(ef.createMethodExpression(elc, "#{myBean.test}", null, new Class[] {}));
    ((InputText)table.getColumns().get(0).getChildren().get(0)).addClientBehavior("change", ajax);

    table.getColumns().addAll(columns);
    table.setValue(mockListSoWeGetOneRowInDatatable);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...