Jsf 2 如何对ajax请求强制子树进程

Jsf 2 如何对ajax请求强制子树进程,jsf-2,Jsf 2,我想在ajax请求上执行JSF UI组件子树的processDecodes。 如果我指定以下内容,我会更详细一些: <f:ajax event="change" execute="componentId" render="componentPanelId" /> 假设我已经在自定义组件中实现了ajax行为,具有属性execute和render。 当ComponentIDAjax事件触发时,我将按照指定的顺序处理id为“root”、“element”和“componentId”的组件

我想在ajax请求上执行JSF UI组件子树的
processDecodes
。 如果我指定以下内容,我会更详细一些:

<f:ajax event="change" execute="componentId" render="componentPanelId" />
假设我已经在自定义组件中实现了ajax行为,具有属性
execute
render
。 当ComponentIDAjax事件触发时,我将按照指定的顺序处理id为“root”、“element”和“componentId”的组件

我尝试使用
@form
作为执行属性值:

<m:selectOne id="componentId" ref="@Attribute1" execute="@form" render="toRender">
    ...
</m:selectOne>   

...
它可以工作,因为JSF处理表单中的所有ui组件,但这不是期望的行为

也许可以通过扩展
PartialViewContextFactory

任何提示或帮助都将不胜感激
谢谢

我找到了一个解决方案,可能不是性能最好的。 我扩展了
PartialViewContextFactory
,包装了原始的
PartialViewContextFactory

新类(如下所示)执行以下操作:

1) 它创建一个新的
CustomPartialViewContextImpl
并将原始
PartialViewContext
传递给它。 2) 它重写
CustomPartialViewContextImpl.getExecuteIds()
,以查找所有祖先

关于id列表的说明,应该从根到叶排序

感谢巴卢斯克的邀请

公共类CustomPartialViewContextFactory扩展了PartialViewContextFactory{
公共静态类CustomPartialViewContextImpl扩展了PartialViewContext{
专用FacesContext FacesContext;
私有PartialViewContext wrappedViewContext;
/**
*要在ajax请求期间执行的Id。
*/
私人收藏管理员;
公共自定义PartialViewContextImpl(PartialViewContext wrappedViewContext,FacesContext FacesContext){
this.facesContext=facesContext;
this.wrappedViewContext=wrappedViewContext;
}
公共集合getExecuteId(){
如果(this.executeIds==null){
this.executeIds=findAncestors(executeIds);
}
返回this.executeIds;
}
//…将其他方法委托给wrappedViewContext
私人收藏findAncestors(收藏执行器ID){
Set id=新的HashSet(executeIds);
for(字符串id:ExecuteID){
findAncestors(id,findComponent(id,facesContext));
}
List idList=new ArrayList(id);
集合。反向(idList);
返回懒汉;
}
私有UIComponent findComponent(最终字符串id,FacesContext上下文){
UIViewRoot root=context.getViewRoot();
最终UIComponent[]找到=新UIComponent[1];
root.visitTree(新的FullVisitContext(上下文),新的VisitCallback(){
@凌驾
公共访问结果访问(VisitContext上下文,UIComponent组件){
if(component.getId().equals(id)){
找到[0]=组件;
返回VisitResult.COMPLETE;
}
返回VisitResult.ACCEPT;
}
});
返回找到[0];
}
专用void findAncestors(设置ID、UIComponent){
如果(组件==null){
返回;
}
UIComponent parent=component.getParent();
如果(父项==null){
返回;
}
字符串clientId=parent.getClientId(facesContext);
if(StringUtils.isBlank(clientId)| | ids.contains(clientId)){
返回;
}
id.add(clientId);
findAncestors(ID、父级);
}
}
私有PartialViewContextFactory父工厂;
公共CustomPartialViewContextFactory(PartialViewContextFactory父工厂){
this.parentFactory=parentFactory;
}
@凌驾
公共PartialViewContext getPartialViewContext(FacesContext上下文){
返回新的CustomPartialViewContextImpl(parentFactory.getPartialViewContext(context),context);
}
@凌驾
公共PartialViewContextFactory getWrapped(){
将此文件退回工厂;
}
}

听起来像是巴卢斯克的问题:)
<m:selectOne id="componentId" ref="@Attribute1" execute="@form" render="toRender">
    ...
</m:selectOne>   
    public class CustomPartialViewContextFactory extends PartialViewContextFactory {

        public static class CustomPartialViewContextImpl extends PartialViewContext {

            private FacesContext facesContext;
            private PartialViewContext wrappedViewContext;

            /**
             * Id to execute during ajax request.
             */
            private Collection<String> executeIds;

            public CustomPartialViewContextImpl(PartialViewContext wrappedViewContext, FacesContext facesContext) {
                this.facesContext = facesContext;
                this.wrappedViewContext = wrappedViewContext;
            }

            public Collection<String> getExecuteIds() {
                if(this.executeIds == null){                
                    this.executeIds = findAncestors(executeIds);
                }

                return this.executeIds;
            }

            // ... delegate other methods to wrappedViewContext

            private Collection<String> findAncestors(Collection<String> executeIds) {
                Set<String> ids = new HashSet<>(executeIds);
                for (String id : executeIds) {
                    findAncestors(ids, findComponent(id, facesContext));
                }


                List<String> idList = new ArrayList<>(ids);
                Collections.reverse(idList);
                return idList;
            }

            private UIComponent findComponent(final String id,  FacesContext context){
                UIViewRoot root = context.getViewRoot();
                final UIComponent[] found = new UIComponent[1];
                root.visitTree(new FullVisitContext(context), new VisitCallback() {
                    @Override
                    public VisitResult visit(VisitContext context, UIComponent component) {
                        if(component.getId().equals(id)){
                            found[0] = component;
                            return VisitResult.COMPLETE;
                        }
                        return VisitResult.ACCEPT;
                    }
                });
                return found[0];
            }

            private void findAncestors(Set<String> ids, UIComponent component) {

                if(component == null){
                    return;
                }

                UIComponent parent = component.getParent();

                if (parent == null) {
                    return;
                }


                String clientId = parent.getClientId(facesContext);
                if (StringUtils.isBlank(clientId) || ids.contains(clientId)) {
                  return;
                }

                ids.add(clientId);                                  

                findAncestors(ids, parent);
            }

        }

        private PartialViewContextFactory parentFactory;

        public CustomPartialViewContextFactory(PartialViewContextFactory parentFactory) {
            this.parentFactory = parentFactory;
        }

        @Override
        public PartialViewContext getPartialViewContext(FacesContext context) {
            return new CustomPartialViewContextImpl(parentFactory.getPartialViewContext(context), context);
        }

        @Override
        public PartialViewContextFactory getWrapped() {
            return this.parentFactory;
        }

    }