現在、ajaxリクエスト中にJSFコンポーネントツリーに新しいコンポーネントを動的に追加しようとしています。
実際、私はAjaxBehaviorListenerのUIViewRootコンポーネントに子を追加します。これは、ajaxリクエストプロセス中にサーバー側で起動されます。
問題は、新しいコンポーネントがレンダリングされないことです。このコンポーネントは、レンダリング応答フェーズでは考慮されていないようです。
この問題について私を助けてくれませんか?
よろしく、
ギヨーム
現在、ajaxリクエスト中にJSFコンポーネントツリーに新しいコンポーネントを動的に追加しようとしています。
実際、私はAjaxBehaviorListenerのUIViewRootコンポーネントに子を追加します。これは、ajaxリクエストプロセス中にサーバー側で起動されます。
問題は、新しいコンポーネントがレンダリングされないことです。このコンポーネントは、レンダリング応答フェーズでは考慮されていないようです。
この問題について私を助けてくれませんか?
よろしく、
ギヨーム
このソリューションは、ajax が追加するコンポーネントを要求する前にわかっている場合に機能します。ただし、追加するコンポーネントがわからない場合は機能しません。
私はおそらく解決策を見つけました:
私の解決策は、カスタム PartialViewContext を実装し、PartialResponseWriter のメソッド startInsertAfter または startInsertBefore を使用することです。
機能していますが、追加されたコンポーネントを一時的に配置する必要があります。(uiComponent.setTransient(Boolean.TRUE);)
よろしく、
ギヨーム
これは私のために働く:
他の 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;
}
}
ajax リクエスト中にコンポーネントを動的に追加しようとする代わりに、事前にコンポーネントを定義し、レンダリングされたタグを false に設定してみてください。次に、コンポーネントのコンテンツに ajax リクエストを入力し、レンダリングされた属性を反転して属性を表示できます。