52

UIComponent私が提供したIDでマネージドBeanからいくつかを見つけたいです。

私は次のコードを書きました:

private UIComponent getUIComponent(String id) {  
      return FacesContext.getCurrentInstance().getViewRoot().findComponent(id) ;  
}

a を次のように定義しp:inputTextareaました。

<p:inputTextarea id="activityDescription" value="#{adminController.activityDTO.activityDescription}" required="true" maxlength="120"
    autoResize="true" counter="counter" counterTemplate="{0} characters remaining." cols="80" rows="2" />

メソッドを呼び出すgetUIComponent("activityDescription")と が返されますがnull、そのように呼び出すとgetUIComponent("adminTabView:activityForm:activityDescription")、インスタンスを取得できorg.primefaces.component.inputtextarea.InputTextareaます。

「adminTabView:activityForm:activityDescription」などの絶対 ID ではなく、「activityDescription」という ID のみを持つコンポーネントを取得する方法はありますか?

4

5 に答える 5

50

次のコードを使用できます。

public UIComponent findComponent(final String id) {

    FacesContext context = FacesContext.getCurrentInstance(); 
    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 != null 
                && id.equals(component.getId())) {
                found[0] = component;
                return VisitResult.COMPLETE;
            }
            return VisitResult.ACCEPT;              
        }
    });

    return found[0];

}

このコードは、渡されたツリー内の最初のコンポーネントのみを検索しidます。ツリーに同じ名前のコンポーネントが 2 つある場合は、何らかのカスタムを行う必要があります (これは、2 つの異なる名前付けコンテナーの下にある場合に可能です)。

于 2013-01-17T12:40:39.213 に答える
1

多分それは不可能です。このFacesContext.getCurrentInstance().getViewRoot().findComponent(id)メソッドは 1 つだけを返しますUIComponent。ViewRoot はツリーとして構築されるため、ビューに 2 つのフォームがあり、それぞれに のコンポーネントがid="text"ある場合、競合しないように親コンポーネントが id に追加されます。2 つのid="text"コンポーネントを同じフォーム内に配置すると、java.lang.IllegalStateExceptionスローされます。

検索された ID を持つすべてのコンポーネントを見つけたい場合は、以下を実装するメソッドを作成できます。

List<UIComponent> foundComponents = new ArrayList();
for(UIComponent component: FacesContext.getCurrentInstance().getViewRoot().getChildren()) {
    if(component.getId().contains("activityDescription")){
        foundComponents.add(component);
    }
}

または、最初に出現したものを見つけたい場合:

UIComponent foundComponent;
for(UIComponent component: FacesContext.getCurrentInstance().getViewRoot().getChildren()) {
    if(component.getId().contains("activityDescription")){
        foundComponent = component;
        break;
    }
}
于 2013-01-17T12:14:35.163 に答える
1

prependId="false"このテキストエリアがあるフォームに置くだけです。

于 2013-01-17T13:05:10.190 に答える
0

NamingContainersはい、属性を追加する必要があるすべての親コンポーネントで、確実に機能し、他のコンポーネントでも機能するはずですprependId="false"。.xhtml ファイルの属性で設定できない場合は、そのような値をプログラムで設定する必要があります。<h:form>

質問の著者コメント後の提案:

使用しているコンポーネントにそのような属性がない場合は、find メソッドを次のように記述してみてください。

private UIComponent findComponent(String id, UIComponent where) {
if (where == null) {
   return null;
}
else if (where.getId().equals(id)) {
   return where;
}
else {
   List<UIComponent> childrenList = where.getChildren();
   if (childrenList == null || childrenList.isEmpty()) {
      return null;
   }
   for (UIComponent child : childrenList) {
      UIComponent result = null;
      result = findComponent(id, child);
      if(result != null) {
         return result;
   }
   return null;
}   

次は呼び出すだけ

UIComponent iamLookingFor = findComponent(myId, FacesContext.getCurrentInstance().getViewRoot());

それは助けになりますか?

于 2013-01-17T11:54:00.047 に答える