Как я могу передать выбранную строку в commandLink внутри dataTable или ui: repeat?
Я использую Primefaces в приложении JSF 2. У меня есть <p:dataTable>
, и вместо того, чтобы выбирать строки, Я хочу, чтобы пользователь мог напрямую выполнять различные действия над отдельными строками. Для этого у меня есть несколько <p:commandLink>
s в последней колонке.
моя проблема: как я могу передать идентификатор строки в действие, начатое по командной ссылке, чтобы я знал, на какую строку действовать? Я пробовал использовать <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>
но он всегда дает 0-видимо, переменная строки f
не доступно, когда атрибут отображается (он работает, когда я использую фиксированное значение).
у кого-нибудь есть альтернативное решение?
4 ответа:
что касается причины, то
<f:attribute>
относится к самому компоненту (заполняется во время построения представления), а не к итерационной строке (заполняется во время визуализации представления).существует несколько способов достижения этого требования.
использовать
<f:param>
. Он добавляет параметр запроса.<h:commandLink action="#{bean.insert}" value="insert"> <f:param name="id" value="#{item.id}" /> </h:commandLink>
если ваш Боб имеет область запроса, пусть JSF установит его на
@ManagedProperty
@ManagedProperty(value="#{param.id}") private Long id; // +setter
или если ваш Боб имеет более широкую область действия или если вы хотите более мелкозернистую проверку / преобразование, используйте
<f:viewParam>
на целевом представлении см. также f: viewParam vs @ManagedProperty:<f:viewParam name="id" value="#{bean.id}" required="true" />
в любом случае, это имеет то преимущество, что datamodel не обязательно должен быть сохранен для формы submit (для случая, когда ваш bean-это область запроса).
<h:commandLink action="#{bean.insert}" value="insert"> <f:setPropertyActionListener target="#{bean.id}" value="#{item.id}" /> </h:commandLink>
в сочетании с
private Long id; // +setter
он будет просто доступен по свойству
id
в способ действий. Для этого требуется только сохранить модель данных для запроса на отправку формы. Лучше всего поместить боб в область видимости с помощью@ViewScoped
.
если ваш servletcontainer поддержка сервлетов 3.0 / EL 2.2, затем просто передайте его в качестве аргумента метода. Это также требует, чтобы модель данных сохранялась для формы отправить запрос. Лучше всего поместить боб в область видимости с помощью
@ViewScoped
.<h:commandLink action="#{bean.insert(item.id)}" value="insert" />
в сочетании с:
public void insert(Long id) { // ... }
вы даже можете передать весь объект элемента:
<h:commandLink action="#{bean.insert(item)}" value="insert" />
С:
public void insert(Item item) { // ... }
на контейнерах сервлета 2.5 это также возможно, если вы предоставляете реализацию EL, которая поддерживает это, например, как JBoss EL. Для подробности конфигурации см. ответ.
привязать значение datatable к
DataModel<E>
вместо этого, который, в свою очередь, обхватывает предметы.<h:dataTable value="#{bean.model}" var="item">
С
private transient DataModel<Item> model; public DataModel<Item> getModel() { if (model == null) { model = new ListDataModel<Item>(items); } return model; }
(делая это
transient
и лениво инстанцирование его в геттере является обязательным, когда вы используете это в представлении или сеансе с областью действия bean sinceDataModel
не выполнятьSerializable
)тогда вы сможете чтобы получить доступ к текущей строке с помощью
DataModel#getRowData()
не передавая ничего вокруг (JSF определяет строку на основе имени параметра запроса нажатой командной ссылки/кнопки).public void insert() { Item item = model.getRowData(); Long id = item.getId(); // ... }
это также требует, чтобы модель данных была сохранена для формы отправить запрос. Лучше всего поместить боб в область видимости с помощью
@ViewScoped
.
можно использовать
Application#evaluateExpressionGet()
для программной оценки текущего#{item}
.public void insert() { FacesContext context = FacesContext.getCurrentInstance(); Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class); Long id = item.getId(); // ... }
какой путь выбрать зависит от функциональных требований и предлагает ли одно или другое больше преимуществ для других целей. Я лично пошел бы вперед с #3 или, когда вы хотите поддерживать контейнеры servlet 2.5, с #2.
в JSF 1.2 это было сделано
<f:setPropertyActionListener>
(в командной составляющей). В JSF 2.0 (EL 2.2, если быть точным, благодаря BalusC) это можно сделать так:action="${filterList.insert(f.id)}
на моей странице просмотра:
<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>
базовый компонент
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; } } }
спасибо этот сайт от Mkyong единственное решение, которое на самом деле работали для нас, чтобы передать параметр был этот
<h:commandLink action="#{user.editAction}"> <f:param name="myId" value="#{param.id}" /> </h:commandLink>
С
public String editAction() { Map<String,String> params = FacesContext.getExternalContext().getRequestParameterMap(); String idString = params.get("myId"); long id = Long.parseLong(idString); ... }
технически, что вы не можете перейти непосредственно к самому методу, но к
JSF request parameter map
.