作者: sealyu 日期:2009-05-06
在Seam中,如果要提供一个集合属性传到页面,那么可以有两种选择:
(1).在SFSB中建一个集合属性,并建立一个方法用来取得对应的数据。例如我们有一个SFSB(TestAction.java):
@Stateful
@Name("testPerson")
public class TestAction extends TestActionLocal implements Serializable{
protected List<Person> personList;
public List<Person> getPersonList(){
//得到对应数据
}
}
每次在前台页面调用的时候可以直接使用:
<rich:dataTable value="#{testPerson.personList}" id="xxx"/>.
但是这种方法有种缺点,因为将对应的值赋值给一个JSF组件,所以在刷新一个页面的时候经常需要调用很多次取数据的函数,即使你作判断(例如:当值不为空的时候不再重新取值),这个函数还是会执行很多次,可能会造成效率的问题。
但是这种方法的好处是总是可以取得最新的数据。在你经常通过传递参数来取得数据列表的时候,这种方法比较好。
(2).使用@Factory.
@Factory有两种,在它的javadoc里面是这么说的:
* Marks a method as a factory method for a context variable.
* A factory method is called whenever no value is bound to
* the named context variable, and is expected to initialize
* the value of the context variable. There are two kinds of
* factory methods. Factory methods with void return type are
* responsible for outjecting a value to the context variable.
* Factory methods which return a value do not need to
* explicitly ouject the value, since Seam will bind the
* returned value to the specified scope.
第一种工厂方法:
这种工厂方法没有返回值,但是你需要将得到的数据注出到context里面,大多数情况下你可以直接使用@DataModel,例如:
@Stateful
@Name("testPerson")
public class TestAction extends TestActionLocal implements Serializable{
@DataModel
protected List<Person> personList;
@Factory(value="personList", autoCreate=true)
public void getPersonList(){
//得到对应数据
this.personList=mgr.createQuery....
}
}
第二种工厂方法:
这种工厂方法有返回值,seam会根据scope的值将数据绑定到对应的上下文中。使用这种方法,你不用显式的注出。例如:
@Stateful
@Name("testPerson")
public class TestAction extends TestActionLocal implements Serializable{
protected List<Person> personList;
@Factory(value="personList", autoCreate=true)
public List<Person> getPersonList(){
//得到对应数据
this.personList=mgr.createQuery....
return personList;
}
}
不管使用哪种方法,你都可以在页面中直接访问这个factory的值:
<rich:dataTable value="#{personList}" id="xxx"/>
使用@Factory的好处是不用重复的去取值,但是同时也有一个缺点:
使用@Factory的时候,只有在context中没有这个@Factory所对应的绑定值的时候,seam才会重新执行工厂方法来取得这个值。所以如果你想要在CRUD一个实体之后更新列表的话,你可以监听org.jboss.seam.afterTransactionSuccess.XXEntity事件来更新这个@Factory的值。暂时没找到强制清空并刷新@Factory的方法,seam好像现在并没有提供这个方法,所以我现在是直接清空@Factory所对应的list的值来达到刷新的目的。