선택한 행을 dataTable 또는 ui : repeat 내의 commandLink에 어떻게 전달할 수 있습니까?
JSF 2 응용 프로그램에서 Primefaces를 사용하고 있습니다. 나는을 가지고 있으며 <p:dataTable>
행을 선택하는 대신 사용자가 개별 행에서 다양한 작업을 직접 실행할 수 있기를 원합니다. 이를 위해 <p:commandLink>
마지막 열에 여러 개의 s가 있습니다.
내 문제 : 명령 링크로 시작된 작업에 행 ID를 전달하여 작업 할 행을 어떻게 알 수 있습니까? 나는 사용을 시도했다 <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
속성이 렌더링 될 때 행 변수 를 사용할 수 없습니다 (고정 값을 사용할 때 작동합니다).
누구든지 대체 솔루션이 있습니까?
원인 <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 대 @ManagedProperty 도 참조하십시오 .<f:viewParam name="id" value="#{bean.id}" required="true" />
어느 쪽이든, 이것은 양식 제출을 위해 데이터 모델을 반드시 보존 할 필요가 없다는 장점이 있습니다 (빈이 요청 범위 인 경우).
<f:setPropertyActionListener>
대신 사용하십시오 . 장점은 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가 Servlet 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) { // ... }
Servlet 2.5 컨테이너에서는 JBoss EL과 같이이를 지원하는 EL 구현을 제공하는 경우에도 가능합니다. 구성 세부 정보는 이 답변을 참조하십시오 .
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; }
(making it
transient
and lazily instantiating it in the getter is mandatory when you're using this on a view or session scoped bean sinceDataModel
doesn't implementSerializable
)Then you'll be able to access the current row by
DataModel#getRowData()
without passing anything around (JSF determines the row based on the request parameter name of the clicked command link/button).public void insert() { Item item = model.getRowData(); Long id = item.getId(); // ... }
This also requires that the datamodel is preserved for the form submit request. Best is to put the bean in the view scope by
@ViewScoped
.You can use
Application#evaluateExpressionGet()
to programmatically evaluate the current#{item}
.public void insert() { FacesContext context = FacesContext.getCurrentInstance(); Item item = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class); Long id = item.getId(); // ... }
Which way to choose depends on the functional requirements and whether the one or the other offers more advantages for other purposes. I personally would go ahead with #3 or, when you'd like to support servlet 2.5 containers as well, with #2.
In JSF 1.2 this was done by <f:setPropertyActionListener>
(within the command component). In JSF 2.0 (EL 2.2 to be precise, thanks to BalusC) it's possible to do it like this: action="${filterList.insert(f.id)}
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;
}
}
}
Thanks to this site by Mkyong, the only solution that actually worked for us to pass a parameter was this
<h:commandLink action="#{user.editAction}">
<f:param name="myId" value="#{param.id}" />
</h:commandLink>
with
public String editAction() {
Map<String,String> params =
FacesContext.getExternalContext().getRequestParameterMap();
String idString = params.get("myId");
long id = Long.parseLong(idString);
...
}
Technically, that you cannot pass to the method itself directly, but to the JSF request parameter map
.
'programing tip' 카테고리의 다른 글
CSS를 사용한 텍스트 테두리 (텍스트 테두리) (0) | 2020.08.23 |
---|---|
목록을 초기화하는 방법 (0) | 2020.08.23 |
Go의 기존 유형에 새 메소드를 추가하는 방법은 무엇입니까? (0) | 2020.08.23 |
div의 CSS 워드 랩핑 (0) | 2020.08.23 |
C # : 어셈블리의 모든 클래스 나열 (0) | 2020.08.23 |