Как динамически добавить компонент в JSF2 во время Ajax-запроса - PullRequest
2 голосов
/ 17 апреля 2010

В настоящее время я пытаюсь динамически добавить новый компонент в дерево компонентов JSF во время запроса ajax.

Фактически я добавляю дочерний элемент к компоненту UIViewRoot в моем AjaxBehaviorListener, который запускается на стороне сервера во время процесса запроса ajax.

Проблема в том, что новый компонент не отображается. Похоже, что этот компонент не учитывается на этапе ответа рендеринга.

Не могли бы вы помочь мне в этом вопросе?

С уважением,

Гийом

Ответы [ 3 ]

2 голосов
/ 20 апреля 2010

Это решение работает, если вы знаете, прежде чем ajax запросит компонент для добавления. Но если вы не можете знать, какой компонент добавить, он не работает.

Возможно, я нашел решение:

Мое решение заключается в реализации моего пользовательского PartialViewContext и использовании метода startInsertAfter или startInsertBefore из PartialResponseWriter.

Это работает, но вы должны поместить добавленный компонент как временный. (UiComponent.setTransient (Boolean.TRUE);)

С уважением,

Гийом

2 голосов
/ 28 марта 2011

Это работает для меня:

Бин, содержащий привязку к UIComponent, в которую вы хотите динамически добавлять другие UIComponent, должен быть ограничен запросом, в противном случае он может вызвать некоторые неприятные исключения (не спрашивайте меня почему):

   @ManagedBean
    @RequestScoped
    public class AddressEditorBean {
// session bean reference for holding id number line and model
        @ManagedProperty(value = "#{addressValueBean}")
        private AddressValueBean address;     
        public String addOutputText() {
            HtmlOutputText text = new HtmlOutputText();
            int c = address.getC();
            text.setValue("new text! " + c);
            text.setId("id" + c++);
            address.setC(c);              // hold id number line in sessionbean
            address.getComps().add(text); // hold new uicomponent in session bean to be able to rebuild it
            panel.getChildren().clear();  // need to clear children and add them all again,
            panel.getChildren().addAll(address.getComps()); // otherwise there are problems with duplicate children (bug?)
            return "success";
        }

        public HtmlPanelGroup getPanel() {
            return panel;
        }

        public void setPanel(HtmlPanelGroup pane) {
            if (panel == null) {
                this.panel = pane;
                if (panel != null) {
                    panel.getChildren().addAll(address.getComps());
                }
            } else {
                this.panel = pane;
            }
        }
    }

фрагмент кода со страницы. Я динамически добавляю компоненты к <h:panelGroup>

 <h:form>
        <h:panelGroup id="section" binding="#{addressEditorBean.panel}">

        </h:panelGroup>
        <h:commandButton value="add new text" action="#{addressEditorBean.addOutputText}">
            <f:ajax execute="@this" render="section" event="action"/>
        </h:commandButton>
    </h:form>

В бине Session я держу актуальную динамическую модель, чтобы я мог перестроить ее после перезагрузки страницы:

@ManagedBean
@SessionScoped
public class AddressValueBean extends ValueBean<Address> {

    private int c = 0;
    private List<UIComponent> comps = new ArrayList<UIComponent>();

    public AddressValueBean() {
        setValue(new Address());
    }

    public int getC() {
        return c;
    }

    public void setC(int cn) {
        this.c = cn;
    }

    public List<UIComponent> getComps() {
        return comps;
    }

    public void setComps(List<UIComponent> comps) {
        this.comps = comps;
    }
}
1 голос
/ 20 апреля 2010

Вместо того, чтобы пытаться динамически добавлять компонент во время запроса ajax, попробуйте определить компонент сразу и установить для его отображаемого тега значение false.Содержимое компонента затем может быть заполнено запросом ajax, а отображаемый атрибут перевернут для отображения атрибута.

...