Ich möchte einige UIComponent
von Managed Bean anhand der von mir angegebenen ID finden.
Ich habe folgenden Code geschrieben:
private UIComponent getUIComponent(String id) {
return FacesContext.getCurrentInstance().getViewRoot().findComponent(id) ;
}
Ich habe einen p:inputTextarea
definiert als:
<p:inputTextarea id="activityDescription" value="#{adminController.activityDTO.activityDescription}" required="true" maxlength="120"
autoResize="true" counter="counter" counterTemplate="{0} characters remaining." cols="80" rows="2" />
Wenn nun die Methode als getUIComponent("activityDescription")
aufgerufen wird, wird null
zurückgegeben. Wenn ich sie jedoch als getUIComponent("adminTabView:activityForm:activityDescription")
aufrufe, kann ich die org.primefaces.component.inputtextarea.InputTextarea
-Instanz abrufen.
Gibt es eine Möglichkeit, die Komponente nur mit der ID zu erhalten, d. H. "ActivityDescription", nicht mit der absoluten ID, d.
Sie können den folgenden Code verwenden:
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];
}
Dieser Code findet nur die erste Komponente in der Baumstruktur mit dem von Ihnen übergebenen id
. Sie müssen etwas anpassen, wenn zwei Komponenten mit demselben Namen in der Baumstruktur vorhanden sind (dies ist möglich, wenn sie unter zwei verschiedenen Namenscontainern liegen).
Ich versuche diesen Code, und es hilft:
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;
}
Vielen Dank
Geben Sie einfach prependId="false"
in Ihr Formular ein, in dem sich dieser Textbereich befindet.
Vielleicht ist es nicht möglich. Die FacesContext.getCurrentInstance().getViewRoot().findComponent(id)
-Methode gibt nur eine UIComponent
zurück. ViewRoot ist als Baumstruktur aufgebaut. Wenn Sie also zwei Formulare in der Ansicht haben, jedes mit einer Komponente mit id="text"
, werden die übergeordneten Komponenten zur ID hinzugefügt, damit sie nicht in Konflikt stehen. Wenn Sie die beiden id="text"
-Komponenten in dasselbe Formular einfügen, wird Java.lang.IllegalStateException
ausgegeben.
Wenn Sie alle Komponenten mit der gesuchten ID suchen möchten, können Sie eine Methode schreiben, die Folgendes implementiert:
List<UIComponent> foundComponents = new ArrayList();
for(UIComponent component: FacesContext.getCurrentInstance().getViewRoot().getChildren()) {
if(component.getId().contains("activityDescription")){
foundComponents.add(component);
}
}
Oder wenn Sie das erste Vorkommen suchen möchten:
UIComponent foundComponent;
for(UIComponent component: FacesContext.getCurrentInstance().getViewRoot().getChildren()) {
if(component.getId().contains("activityDescription")){
foundComponent = component;
break;
}
}
Ja, in allen übergeordneten Komponenten, die NamingContainers
sind, müssen Sie das Attribut prependId="false"
hinzufügen - es funktioniert sicher in <h:form>
und sollte in anderen funktionieren.
Wenn es nicht möglich ist, es über ein Attribut in der .xhtml-Datei festzulegen, müssen Sie den Wert programmgesteuert festlegen.
Vorschlag nach Autorenkommentar der Frage:
Wenn ein solches Attribut in den von Ihnen verwendeten Komponenten nicht vorhanden ist, versuchen Sie die find-find-Methode wie folgt:
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;
}
Als nächstes einfach aufrufen
UIComponent iamLookingFor = findComponent(myId, FacesContext.getCurrentInstance().getViewRoot());
Das wird helfen?