Richfaces - Ajax ReRender funktioniert nicht

Nexi

Grünschnabel
Hu Leute, bin etwas am verzweifeln.

Folgendes Problem:
Ich habe auf meine Seite ein PanelGrid welches ein paar weitere Elemente enthält. Dieses wird mittel Java erstellt und über das binding attribut an dieses Element gebunden. Was soweit auch super funktioniert. Allerdings möchte ich über einen Button eine bestimmte Zeile löschen. Das funktioniert auch noch soweit ;)

Nun der haken.
Über das ReRender attribute des commandbuttons (a4j / richfaces) möchte ich gern dieses PanelGrid refreshen,
was allerdings nichtmal im ansatz funktioniert. Es passiert einfach garnichts.

Hier mal die JSP:
Code:
<a4j:form ajaxSubmit="true">

<a4j:outputPanel id="panel">
   <h:panelGrid binding="#{controller.companyList}"/>
</a4j:outputPanel>

<a4j:commandButton value="refresh" action="#{controller.delRow}" reRender="panel" ajaxSingle="true"/>
</a4j:form>

Und hier der JAVA-Code:
Code:
public HtmlPanelGrid getCompanyList()
{
   if(this.m_CompanyList == null)
   {
      // Genarate Pilotcompanies
      this.m_CompanyList = CompanyPanelGrid.getInstance();
      this.m_CompanyList.generateGrid();
   }
   
   return this.m_CompanyList.getHtmlGrid();
}

public void delRow()
{
   // AjaxContext holen
   AjaxContext lAjaxContext = AjaxContext.getCurrentInstance();
   // ComponentID suchen welche geschickt wurde (z.B. die eines Buttons);
   String lComponentId = lAjaxContext.getAjaxSingleClientId();
   // Eintrag löschen
   this.m_CompanyList.removeEntry(lComponentId);
      
   lAjaxContext = null;
   lComponentId = null;
}

Wichtig ist vielleicht noch, das ich aktuelle immer das erste Element aus der Liste lösche, falls sich jemand wundert ;)

Wenn ich andere Element nehmen, zb outputText etc und mache dort die Simpelsten Ajax-Requests, funktioniert es.
Also Text setzen, dann ReRender angeben und anzeigen... nur bei dem PanelGrid nicht.

Hoffentlich könnt ihr mir weiterhelfen.
Danke schonmal
 
Zuletzt bearbeitet:
Ich könnte mir vorstellen, dass dein "return this.m_CompanyList.getHtmlGrid();" noch die alten Werte gespeichert hat und somit sich deswegen nichts verändert. Sprich, es wird das Element gelöscht (Zb aus der Datenbank) aber deine companyList nicht neu generiert und somit die alte Liste zurückgegeben.
 
das getHtmlGrid nimmt die membervariablen (sprich die in diesem objekt gespeicherte liste) welche ich vorher durch delRow manipuliere.

Das Problem liegt eher dabei, das er bei dem AjaxRequest nicht nochmal durch die Methode läuft, so wie er es bei allen anderen "Refresh Requests" machen würde.

Wenn ich dort nen breakpoint einbaue, passiert nichts ;)
 
Lösung gefunden.

AjaxReRender und panelGrid mit binding verträgt sich nicht.
Warum? Steht in den Sternen ;)

Hab das ganze nun mit einem Richfaces dataTable tag erstellt.
Hier meine Lösung für die, die evtl ähnliche Probleme haben.

Hier die *.jsp seite:
HTML:
<r:dataTable width="100%" id="companyList" styleClass="companyTable" columns="5" value="#{controller.companyList}" var="list">
	<f:facet name="header">
	    <r:columnGroup>
	        <r:column width="40%">
	            <h:outputText value="Name" />
	        </r:column>
	        <r:column width="45%">
	            <h:outputText value="URL" />
	        </r:column>
	        <r:column width="5%">
	            <r:spacer/>
	        </r:column>
	        <r:column width="5%">
	            <r:spacer/>
	        </r:column>
	        <r:column width="5%">
	            <r:spacer/>
	        </r:column>
	    </r:columnGroup>
	</f:facet>

	<r:subTable value="#{list.companyList}" var="company">
		<r:column>
			<input type="text" value="<h:outputText value="#{company.name}"/>" id="<h:outputText value="companyName_#{company.id}"/>"/>
		</r:column>
		<r:column>
			<input type="text" value="<h:outputText value="#{company.url}"/>" id="<h:outputText value="companyURL_#{company.id}"/>"/>
		</r:column>
		<r:column>
			<a4j:commandLink action="#{list.delRow}" reRender="companyList">
				<h:graphicImage url="img/bt_form_row_delete.gif" styleClass="imageButton"/>
				<a4j:actionparam name="companyDelId" value="#{company.id}" assignTo="#{controller.selectedCompany}"/>
			</a4j:commandLink>
		</r:column>
		<r:column>
			<a4j:commandLink ajaxSingle="true" action="#{list.addAbove}" reRender="companyList">
				<h:graphicImage url="img/bt_form_row_above.gif" styleClass="imageButton"/>
				<a4j:actionparam name="companyAboveId" value="#{company.id}" assignTo="#{list.selectedCompany}"/>
			</a4j:commandLink>
		</r:column>
		<r:column>
			<a4j:commandLink action="#{list.addBelow}" reRender="companyList">
				<h:graphicImage url="img/bt_form_row_below.gif" styleClass="imageButton"/>
				<a4j:actionparam name="companyBelowId" value="#{company.id}" assignTo="#{list.selectedCompany}"/>
			</a4j:commandLink>
		</r:column>
	</r:subTable>
</r:dataTable>

Hier die funktion für den Controller:
Code:
        /**
	 * Liefert die aktuellen Pilotunternehmensliste
	 * @return List<Company>
	 */
	public CompanyList getCompanyList()
	{
		if(this.m_CompanyList == null)
		{
			this.m_CompanyList = new CompanyList();
			this.m_CompanyList.createCompany("test1", "url1");
			this.m_CompanyList.createCompany("test2", "url2");
		}
		
		return this.m_CompanyList;
	}
	
	/**
	 * Setzt die ID des aktuelle ausgewählten Unternehmens
	 * Notwendig das AJAX Request mit Parameter nur bis zum Controller geht
	 * @param pId ID des Unternehmens
	 */
	public void setSelectedCompany(int pId)
	{
		this.m_CompanyList.setSelectedCompany(pId);
	}

Und hier die beiden HelperKlassen:
Code:
public class Company 
{
	private String m_companyName = null;
	private String m_companyUrl  = null;
	private int	   m_companyId;
	
	/**
	 * Konstruktor
	 * @param pName Name des Unternehmens
	 * @param pUrl URL des Unternehmens
	 * @param pId ID des Unternehmens
	 */
	public Company(String pName, String pUrl, int pId)
	{
		this.m_companyId = pId;
		this.m_companyName = pName;
		this.m_companyUrl = pUrl;
	}
	
	/**
	 * Liefert den Name des Unternehmens
	 * @return String
	 */
	public String getName()
	{
		return this.m_companyName;
	}
	
	/**
	 * Liefert die URL des Unternehmens
	 * @return String
	 */
	public String getUrl()
	{
		return this.m_companyUrl;
	}
	
	/**
	 * Liefert die ID des Unternehmens
	 * @return String
	 */
	public String getId()
	{
		return ""+this.m_companyId;
	}
}

Code:
public class CompanyList 
{
	/**
	 * Die Liste der Pilotunternehmen
	 */
	private List<Company> m_CompanyList = null;
	/**
	 * Enthällt die aktuelle ID eines Unternehmens
	 */
	private int m_SelectedCompany;
	/**
	 * Gibt an ob ein ActionEvent ausgelöst wurde
	 */
	private boolean m_ActionSent = false;
	
	/**
	 * Standard Konstruktor
	 */
	public CompanyList()
	{
		this.m_CompanyList = new ArrayList<Company>();
	}
	
	/**
	 * Erzeugt ein neues Pilotunternehmen
	 * @param pName Name des Unternehmens
	 * @param pUrl URL des Unternehmens
	 */
	public void createCompany(String pName, String pUrl)
	{
		// Aktuelle Anzahl der Einträge ermitteln
		int lId = this.m_CompanyList.size();
		// Neues Unternehmen erstellen
		Company lCompany = new Company(pName, pUrl, lId);
		// Unternehmen der Liste hinzufügen
		this.m_CompanyList.add(lCompany);
		
		// Garbage colletor
		lCompany = null;
	}
	
	/**
	 * Liefert die Unternehmensliste
	 * @return List<Company>
	 */
	public List<Company> getCompanyList()
	{
		return this.m_CompanyList;
	}
	
	/**
	 * Setzt die ID des aktuelle ausgewählten Unternehmens
	 * @param pId
	 */
	public void setSelectedCompany(int pId)
	{
		this.m_ActionSent = true;
		this.m_SelectedCompany = pId;
	}
	
	/**
	 * Liefert die ID des aktuell ausgewählten Unternehmens
	 * @return int
	 */
	public int getSelectedCompany() 
	{
		return this.m_SelectedCompany;
	}
	
	/**
	 * Löscht die aktuellen Zeile
	 */
	public void delRow()
	{
		if(this.m_ActionSent)
		{
			/**
			 * Die Unternehmensliste durchlaufen
			 */
			for(Iterator<Company> iCompany = this.m_CompanyList.iterator(); iCompany.hasNext();)
			{
				// nächsten Eintrag lesen
				Company lCompany = iCompany.next();
				// Wenn die aktuell ausgewählte UnternehmensID mit der in der Liste übereinstimmt
				// wird dieser Eintrag aus der Liste entfernt.
				if(lCompany.getId().equals(""+this.m_SelectedCompany))
					iCompany.remove();
				
				// Garbage Collector
				lCompany = null;
			}
		}
	}
	
	/**
	 * Fügt eine neue Zeile oberhalb der aktuellen hinzu
	 */
	public void addAbove()
	{
		if(this.m_ActionSent)
		{
			/**
			 * Vorbelegung:
			 * lCurrentIndex gibt den aktuellen der Unternehmensliste an
			 */
			int lCurrentIndex = 0;
			
			/**
			 * Die Unternehmensliste durchlaufen
			 */
			for(Iterator<Company> iCompany = this.m_CompanyList.iterator(); iCompany.hasNext();)
			{
				// nächsten Eintrag lesen
				Company lCompany = iCompany.next();
				// Wenn die aktuell ausgewählte UnternehmensID mit der in der Liste übereinstimmt
				// wird ein neuer Eintrag an dieser Stelle eingefügt
				if(lCompany.getId().equals(""+this.m_SelectedCompany))
				{
					// Neues Element einfügen
					Company lNewCompany = new Company("test3", "url3", this.m_CompanyList.size());
					this.m_CompanyList.add(lCurrentIndex, lNewCompany);
					
					// Element wurde gefunden und eingefügt
					// Schleife unterbrechen!
					break;
				}
				lCurrentIndex++;
				
				// Garbage Collector
				lCompany = null;
			}
		}
	}
	
	/**
	 * Fügt eine neue Zeile unterhalb der aktuellen hinzu
	 */
	public void addBelow()
	{
		if(this.m_ActionSent)
		{
			/**
			 * Vorbelegung:
			 * lCurrentIndex gibt den aktuellen der Unternehmensliste an
			 */
			int lCurrentIndex = 0;
			
			/**
			 * Die Unternehmensliste durchlaufen
			 */
			for(Iterator<Company> iCompany = this.m_CompanyList.iterator(); iCompany.hasNext();)
			{
				// nächsten Eintrag lesen
				Company lCompany = iCompany.next();
				// Wenn die aktuell ausgewählte UnternehmensID mit der in der Liste übereinstimmt
				// wird ein neuer Eintrag an der nächsten Stelle eingefügt
				if(lCompany.getId().equals(""+this.m_SelectedCompany))
				{
					// Neues Element einfügen
					Company lNewCompany = new Company("test3", "url3", this.m_CompanyList.size());
					this.m_CompanyList.add(lCurrentIndex+1, lNewCompany);
					
					// Element wurde gefunden und eingefügt
					// Schleife unterbrechen!
					break;
				}
				lCurrentIndex++;
				
				// Garbage Collector
				lCompany = null;
			}
		}
	}
}

hoffe das Hilft jemandem vielleicht mit dem gleichen oder ähnlichen Problemen kämpft :)

so long
Nexi
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück