提供したIDでマネージドBeanからUIComponent
を見つけたいです。
私は次のコードを書きました:
_private UIComponent getUIComponent(String id) {
return FacesContext.getCurrentInstance().getViewRoot().findComponent(id) ;
}
_
_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
_インスタンスを取得できます。
絶対IDではなく「adminTabView:activityForm:activityDescription」ではなく、「activityDescription」というIDのみを持つコンポーネントを取得する方法はありますか?
次のコードを使用できます。
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.getId().equals(id)){
found[0] = component;
return VisitResult.COMPLETE;
}
return VisitResult.ACCEPT;
}
});
return found[0];
}
このコードは、id
が渡されたツリーの最初のコンポーネントのみを検索します。ツリー内に同じ名前のコンポーネントが2つある場合は、何らかのカスタム処理を行う必要があります(これらが2つの異なる名前付けコンテナの下にある場合は可能です)。
私はこのコードを試してみましたが、それは助けです:
private static UIComponent getUIComponentOfId(UIComponent root, String id){
if(root.getId().equals(id)){
return root;
}
if(root.getChildCount() > 0){
for(UIComponent subUiComponent : root.getChildren()){
UIComponent returnComponent = getUIComponentOfId(subUiComponent, id);
if(returnComponent != null){
return returnComponent;
}
}
}
return null;
}
ありがとう
ただprependId="false"
このテキストエリアがあるフォームに。
たぶんそれは不可能です。 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;
}
}
はい、NamingContainers
であるすべての親コンポーネントでは、属性prependId="false"
を追加する必要があります。これは<h:form>
で機能し、他のコンポーネントでも機能するはずです。
。xhtmlファイルの属性を介して設定できない場合、そのような値をプログラムで設定する必要があります。
質問の著者のコメントの後の提案:
使用しているコンポーネントにそのような属性がない場合は、次のような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());
それは役立ちますか?