2

現在、ajaxリクエスト中にJSFコンポーネントツリーに新しいコンポーネントを動的に追加しようとしています。

実際、私はAjaxBehaviorListenerのUIViewRootコンポーネントに子を追加します。これは、ajaxリクエストプロセス中にサーバー側で起動されます。

問題は、新しいコンポーネントがレンダリングされないことです。このコンポーネントは、レンダリング応答フェーズでは考慮されていないようです。

この問題について私を助けてくれませんか?

よろしく、

ギヨーム

4

3 に答える 3

2

このソリューションは、ajax が追加するコンポーネントを要求する前にわかっている場合に機能します。ただし、追加するコンポーネントがわからない場合は機能しません。

私はおそらく解決策を見つけました:

私の解決策は、カスタム PartialViewContext を実装し、PartialResponseWriter のメソッド startInsertAfter または startInsertBefore を使用することです。

機能していますが、追加されたコンポーネントを一時的に配置する必要があります。(uiComponent.setTransient(Boolean.TRUE);)

よろしく、

ギヨーム

于 2010-04-20T12:08:58.263 に答える
2

これは私のために働く:

他の UIComponents を動的に追加したい UIComponent へのバインディングを保持する Bean は、リクエスト スコープにする必要があります。

   @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>

セッション Bean では、ページのリロード後に再構築できるように、実際の動的モデルを保持しています。

@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;
    }
}
于 2011-03-27T22:13:04.097 に答える
1

ajax リクエスト中にコンポーネントを動的に追加しようとする代わりに、事前にコンポーネントを定義し、レンダリングされたタグを false に設定してみてください。次に、コンポーネントのコンテンツに ajax リクエストを入力し、レンダリングされた属性を反転して属性を表示できます。

于 2010-04-20T05:16:35.570 に答える