我正在尝试开发和理解类与jsf标签之间的通信。我发现jsf标记直接使用类而不创建任何实例,而当需要在bean之间进行通信时,必须构建该类的实例。迫切需要动态列表,然后将选定的值复制到不同的Bean中,我试图为动态列表构建自定义标签,但在需要将选定的值复制到Bean时需要保留其他Bean的值时遇到了麻烦用于构建列表。
以下是最小的可复制示例
pinnacleTags.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib>
<namespace>pinnacleTags/facelets</namespace>
<tag>
<tag-name>PinnacleCombo</tag-name>
<source>pinnacleCombo.xhtml</source>
<attribute>
<name>actionListenerBeanMethod</name>
</attribute>
</tag>
</facelet-taglib>
列表标签
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:o="http://omnifaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
</h:head>
<h:body>
<ui:composition>
<o:methodParam name="method" value="#{actionListenerBeanMethod}" />
<p:dialog id="dlgTBL" modal="true" showEffect="bounce" widgetVar="dlg" resizable="false">
<p:dataTable var="result" id="tbl" widgetVar="dtlTBL"
value="#{liveRangeService.tableData}"
paginator="false"
scrollable="true" rowIndexVar="rowindex" scrollHeight="500"
scrollRows="50" liveScroll="true"
filterDelay="1100"
selectionMode="single" selection="#{liveRangeService.selectedData}"
rowKey="#{liveRangeService.sr}"
>
<p:ajax event="rowSelect" listener="#{liveRangeService.onRowSelect(rowindex)}" />
<f:facet name="header">
<p:outputPanel layout="inline" styleClass="tabSpacer">
<h:outputText value="Global Filter:" />
<p:inputText id="globalFilter" onkeyup="PF('dtlTBL').filter()" style="width:150px;margin-left:10px;"/>
</p:outputPanel>
</f:facet>
<p:column width="50">
<f:facet name="header">
<h:outputText value="Sr." />
</f:facet>
<p:commandButton value="#{rowindex}" style="width: 49px" action="#{method}"/>
</p:column>
<p:columns value="#{liveRangeService.tableHeaderNames}"
var="mycolHeader"
width="#{colIndex==0?'10%':colIndex==1?'70%':colIndex==2?'10%':colIndex==3?'10%':'0'}"
columnIndexVar="colIndex"
sortBy="#{result[mycolHeader]}"
filterBy="#{result[mycolHeader]}"
filterMatchMode="contains"
>
<f:facet name="header">
<h:outputText value="#{mycolHeader}" />
</f:facet>
<h:outputText value="#{result[mycolHeader]}" />
<br />
</p:columns>
</p:dataTable>
</p:dialog>
</ui:composition>
</h:body>
</html>
动态列表Bean
package classes;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.PrimeFaces;
@ManagedBean(name="liveRangeService", eager = true)
@ApplicationScoped
public class LiveRangeService implements Serializable {
private List< Map<String, String> > tableData;
private Map<String, String> selectedData;
private List< Map<String, String> > filteredData;
private int sr;
private List<String> tableHeaderNames;
private String tableColWidths;
private List< Map<String, String> > selectedRow;
private String RowSelected;
private String CopyValuesToClass;
private String CopyToField;
Object o;
public String getRowSelected() {
return RowSelected;
}
public void setRowSelected(String RowSelected) {
this.RowSelected = RowSelected;
}
public Map<String, String> getSelectedData() {
return selectedData;
}
public void setSelectedData(Map<String, String> selectedData) {
this.selectedData = selectedData;
}
public List<Map<String, String>> getTableData() {
return tableData;
}
public List<String> getTableHeaderNames() {
return tableHeaderNames;
}
public LiveRangeService() {
}
public void LiveRangeServicesss(String Dialogue, String CopyValuesToClass, String CopyToField) {
System.out.println("Qry: " + Dialogue);
this.CopyValuesToClass=CopyValuesToClass;
this.CopyToField=CopyToField;
tableData = new ArrayList< Map<String, String> >();
tableHeaderNames = new ArrayList<String>();
tableHeaderNames.add("ID");
tableHeaderNames.add("Title");
tableHeaderNames.add("Opn_Amt");
tableHeaderNames.add("Smr_Amt");
{
Map<String, String> playlist = new HashMap<String, String>();
playlist.put("ID", "1010001");
playlist.put("Title", "Share Capital - Mr. 1");
playlist.put("Opn_Amt", "0");
playlist.put("Smr_Amt", "0");
tableData.add(playlist);
}
{
Map<String, String> playlist = new HashMap<String, String>();
playlist.put("ID", "1010002");
playlist.put("Title", "Share Capital - Mr. 2");
playlist.put("Opn_Amt", "0");
playlist.put("Smr_Amt", "0");
tableData.add(playlist);
}
{
Map<String, String> playlist = new HashMap<String, String>();
playlist.put("ID", "1010003");
playlist.put("Title", "Share Capital - Mrs. 3");
playlist.put("Opn_Amt", "0");
playlist.put("Smr_Amt", "0");
tableData.add(playlist);
}
System.out.println("RowSelected Variable Values: " + this.sr + ", " + this.RowSelected);
System.out.println("selectedData Select Table Values: " + this.sr + ", " + this.selectedData);
PrimeFaces.current().ajax().update("form:dlgTBL");
PrimeFaces.current().executeScript("PF('dlg').show();");
}
public List<Map<String, String>> getSelectedRow() {
try {System.out.println("Selected Row! " + selectedRow.size());} catch (Exception e) {}
return selectedRow;
}
public void setSelectedRow(List<Map<String, String>> selectedRow) {
// System.out.println( "selected size: " + selectedRow.size() );
this.selectedRow = selectedRow;
}
public String getTableColWidths() {
return tableColWidths;
}
public void setTableColWidths(String tableColWidths) {
this.tableColWidths = tableColWidths;
}
public List<Map<String, String>> getFilteredData() {
return filteredData;
}
public void setFilteredData(List<Map<String, String>> filteredData) {
this.filteredData = filteredData;
}
public void onRowSelect(int row) {
System.out.println("Called For " + CopyValuesToClass + " To Copy Selected Value To " + CopyToField);
try {
test t = new test();
t.id=1233;
t.title="New Value 2";
PrimeFaces.current().ajax().update("form:inp");
PrimeFaces.current().ajax().update("form:inp1");
} catch (Exception ee) {
ee.printStackTrace();
}
}
public int getSr() {
return sr;
}
public void setSr(int Sr) {
this.sr = Sr;
}
}
测试豆
package classes;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Administrator
*/
@ManagedBean(name="test", eager = true)
@SessionScoped
public class test implements Serializable {
public int id;
public String title;
public test() {
id=1;
title="Testing";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
test1 Bean
package classes;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Administrator
*/
@ManagedBean(name="test1", eager = true)
@SessionScoped
public class test1 implements Serializable {
int id;
String title;
public test1() {
id=10;
title="Testing1";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
假设您的问题是如何从applicationScoped test
中访问sessionScopedLiveRangeService
bean:您不能简单地以这种方式实例化ManagedBean
:
test t = new test();
实例由JSF Managed并按需实例化,其寿命由其范围定义。
请阅读How to access property of one managed bean in another managed bean和BalusC链接的博客文章Communication in JSF 2.0 - Injecting managed beans in each other。>
您的示例还有其他一些问题:
class test
重命名为class Test
,将private String CopyValuesToClass;
重命名为private String copyValuesToClass;
@ManagedBean
,请考虑迁移到JSF和CDI的最新版本:Migrate JSF managed beans to CDI managed beans