Jak przekazać wybrany wiersz do commandLink wewnątrz dataTable lub UI: repeat?
Używam Primefaces w aplikacji JSF 2. Mam <p:dataTable>
i zamiast wybierać wiersze, chcę, aby użytkownik mógł bezpośrednio wykonywać różne akcje na poszczególnych wierszach. Do tego mam kilka <p:commandLink>
s w ostatniej kolumnie.
Mój problem: jak mogę przekazać ID wiersza do akcji rozpoczętej przez łącze poleceń, aby wiedzieć, w którym wierszu działać? Próbowałem użyć <f:attribute>
:
<p:dataTable value="#{bean.items}" var="item">
...
<p:column>
<p:commandLink actionListener="#{bean.insert}" value="insert">
<f:attribute name="id" value="#{item.id}" />
</p:commandLink>
</p:column>
</p:dataTable>
Ale zawsze daje 0-widocznie zmienna wiersza f
nie jest dostępna, gdy atrybut jest renderowany (działa, gdy używam stałej wartości).
4 answers
Jeśli chodzi o przyczynę, <f:attribute>
jest specyficzna dla samego komponentu (wypełnionego w czasie budowania widoku), a nie dla iterowanego wiersza (wypełnionego w czasie renderowania widoku).
-
Użycie
<f:param>
zamiast tego. Dodaje parametr request.<h:commandLink action="#{bean.insert}" value="insert"> <f:param name="id" value="#{item.id}" /> </h:commandLink>
Jeśli twój bean jest request scoped, niech JSF ustaw go przez
@ManagedProperty
@ManagedProperty(value="#{param.id}") private Long id; // +setter
Lub jeśli fasola ma szerszy zakres lub jeśli chcesz bardziej drobnoziarniste Walidacja/konwersja, użycie
<f:viewParam>
w tym celu należy zapoznać się z poniższym opisem:viewParam vs @ ManagedProperty :<f:viewParam name="id" value="#{bean.id}" required="true" />
Tak czy inaczej, ma to tę zaletę, że datamodel niekoniecznie musi być zachowany dla formularza submit (w przypadku, gdy twoja fasola jest scopedem żądania).
-
Użycie
<f:setPropertyActionListener>
zamiast tego. Zaletą jest to, że eliminuje to potrzebę dostępu do mapy parametrów żądania, gdy bean ma szerszy zakres niż zakres żądania.<h:commandLink action="#{bean.insert}" value="insert"> <f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" /> </h:commandLink>
W połączeniu z
private Long id; // +setter
Będzie dostępny tylko według właściwości {[18] } w metodzie action. Wymaga to tylko, aby datamodel był zachowany dla żądania przesłania formularza. Najlepiej umieścić fasolę w polu widzenia przez
@ViewScoped
.
-
Jeśli twój servletcontainer obsługuje Servlet 3.0 / EL 2.2, po prostu przekaż go jako argument metody. Wymaga to również, aby datamodel był zachowany dla żądania przesłania formularza. Najlepiej jest umieścić bean in the view scope by
@ViewScoped
.<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
W połączeniu z:
public void insert(Long id) { // ... }
Możesz nawet przekazać cały obiekt elementu:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
Z:
public void insert(Item item) { // ... }
Na kontenerach Servlet 2.5 jest to również możliwe, jeśli dostarczysz implementację EL, która to obsługuje, jak np. JBoss EL. Aby uzyskać szczegóły konfiguracji, zobacz ta odpowiedź .
-
Bind the datatable value to
DataModel<E>
zamiast tego, co z kolei owija pozycji.<h:dataTable value="#{bean.model}" var="item">
Z
private transient DataModel<Item> model; public DataModel<Item> getModel() { if (model == null) { model = new ListDataModel<Item>(items); } return model; }
(tworzenie go
transient
i leniwe tworzenie instancji w getterze jest obowiązkowe, gdy używasz go w widoku lub sesji, ponieważDataModel
nie implementujeSerializable
)Wtedy będziesz mógł uzyskać dostęp do bieżącego wiersza przez
DataModel#getRowData()
bez przekazywania czegokolwiek (JSF określa wiersz na podstawie nazwy parametru żądania klikniętego linku/przycisku polecenia).public void insert() { Item item = model.getRowData(); Long id = item.getId(); // ... }
To również wymaga, aby datamodel jest zachowany dla żądania przesłania formularza. Najlepiej umieścić fasolę w polu widzenia przez
@ViewScoped
.
-
Możesz użyć
Application#evaluateExpressionGet()
aby programowo ocenić prąd#{item}
.public void insert() { FacesContext context = FacesContext.getCurrentInstance(); Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class); Long id = item.getId(); // ... }
Jaki sposób wybrać zależy od wymagań funkcjonalnych i czy jeden lub drugi oferuje więcej korzyści dla innych celów. Ja osobiście bym poszedł na #3 lub, gdy chcielibyście również obsługiwać kontenery servlet 2.5, z numerem 2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:10
W JSF 1.2 zostało to zrobione przez <f:setPropertyActionListener>
(wewnątrz komponentu command). W JSF 2.0 (dokładnie el 2.2, dzięki BalusC) można to zrobić tak: action="${filterList.insert(f.id)}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-14 16:58:28
In my view page:
<p:dataTable ...>
<p:column>
<p:commandLink actionListener="#{inquirySOController.viewDetail}"
process="@this" update=":mainform:dialog_content"
oncomplete="dlg2.show()">
<h:graphicImage library="images" name="view.png"/>
<f:param name="trxNo" value="#{item.map['trxNo']}"/>
</p:commandLink>
</p:column>
</p:dataTable>
Backing bean
public void viewDetail(ActionEvent e) {
String trxNo = getFacesContext().getRequestParameterMap().get("trxNo");
for (DTO item : list) {
if (item.get("trxNo").toString().equals(trxNo)) {
System.out.println(trxNo);
setSelectedItem(item);
break;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-09 08:50:05
Dzięki tej stronie przez Mkyong , jedynym rozwiązaniem, którew rzeczywistości zadziałało dla nas, aby przekazać parametr, było to
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
Z
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technicznie, że nie można przejść do samej metody bezpośrednio, ale do JSF request parameter map
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-20 20:21:10