0

processDecodesajax リクエストで JSF UI コンポーネントのサブツリーを実行したいと思います。指定すると、もう少し詳しく説明します。

<f:ajax event="change" execute="componentId" render="componentPanelId" />

processDecodesUIViewRoot から id componentId を持つコンポーネントまでのすべてのコンポーネント、およびすべての componentId の祖先で呼び出されることを望みます。私がそうするのは、ターゲット コンポーネントの ui カスタム コンポーネントの親が何らかの評価を行うためです。具体的には、UI コンポーネントの値が適用される XML ドキュメントの部分を絞り込みます。

次の facelet フラグメントがあるとします。

 <m:node id="root" ref="/Root">
  <m:node id="element" ref="Element">
    <m:label>Some Label</m:label>
    <m:selectOne id="componentId" ref="@Attribute1" execute="@this" render="toRender">
        ...
    </m:selectOne>
    <m:selectOne id="toRender" ref="@Attribute2">
        ...
    </m:selectOne>
  </m:node>
</m:node>

属性executerender. componentId ajax イベントがトリガーされると、id: 'root'、'element'、'componentId' のコンポーネントを指定された順序で処理します。

@form実行属性値として使用しようとしました:

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

JSF はフォーム内のすべての UI コンポーネントを処理するため、これは機能しますが、これは望ましい動作ではありません。

多分拡張することによってPartialViewContextFactory

ヒントやヘルプをいただければ幸いです ありがとう

4

1 に答える 1

0

解決策を見つけましたが、おそらくパフォーマンスが最高ではありません。PartialViewContextFactoryオリジナルをラッピングして伸ばしましたPartialViewContextFactory

新しいクラス (以下に示す) は、次のことを行います。

1)CustomPartialViewContextImpl元の を渡して新しい を作成しPartialViewContextます。CustomPartialViewContextImpl.getExecuteIds()2)すべての祖先を見つけるために、 をオーバーライドします。

id リストに関する注意。リーフのルートから順に並べる必要があります。

コンポーネントの検索アルゴリズムを提供してくれた BalusC に感謝します。

    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;
        }

    }
于 2013-06-18T14:35:16.173 に答える