我目前正在尝试在 ajax 请求期间向 JSF 组件树动态添加一个新组件。
事实上,我在 AjaxBehaviorListener 中的 UIViewRoot 组件中添加了一个子组件,该组件在 ajax 请求过程中在服务器端触发。
问题是新组件未呈现。在渲染响应阶段似乎没有考虑到这个组件。
你能帮我解决这个问题吗?
问候,
纪尧姆
我目前正在尝试在 ajax 请求期间向 JSF 组件树动态添加一个新组件。
事实上,我在 AjaxBehaviorListener 中的 UIViewRoot 组件中添加了一个子组件,该组件在 ajax 请求过程中在服务器端触发。
问题是新组件未呈现。在渲染响应阶段似乎没有考虑到这个组件。
你能帮我解决这个问题吗?
问候,
纪尧姆
这对我有用:
持有绑定到 UIComponent 的 Bean,您希望在其下动态添加其他 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>
在会话 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 请求要添加的组件之前知道该解决方案,则此解决方案有效。但是,如果您不知道要添加哪个组件,它就不起作用。
我也许找到了解决方案:
我的解决方案是实现我的自定义 PartialViewContext 并使用 PartialResponseWriter 的 startInsertAfter 或 startInsertBefore 方法。
它正在工作,但您必须将添加的组件作为瞬态添加。(uiComponent.setTransient(Boolean.TRUE);)
问候,
纪尧姆
与其尝试在 ajax 请求期间动态添加组件,不如尝试预先定义组件,并将其呈现的标记设置为 false。然后可以使用 ajax 请求填充组件的内容,并翻转呈现的属性以显示该属性。