以编程方式添加的复合组件内的数据表 [英] Datatable inside programatically added composite component
问题描述
参考我之前的问题(以编程方式创建和添加复合支持 bean 中的组件) 我已经成功地从支持 bean 添加复合组件.现在我有一个新问题,因为其中包含惰性数据表的复合组件根本不调用 load() 方法.有关于此的错误报告(https://code.google.com/p/primefaces/issues/detail?id=3258) 但它被标记为与 PF3.0.RC1 相关,我不知道它是否已针对我正在使用的 3.5 版修复.
Referring to my earlier question (Programmatically create and add composite component in backing bean) I have succesfully able to add composite components from backing bean. Now I have a new problem as composite component with lazy datatable in it does not call load() method at all. There was bug report about this (https://code.google.com/p/primefaces/issues/detail?id=3258) but that is marked to be related to PF3.0.RC1 and I have no clue if it is fixed for version 3.5 I am using.
我正在使用与提到的 BalusC 完全相同的代码,可以向复合组件添加值表达式:
I am using the exactly same code BalusC mentioned with possibility to add value expressions to the composite component:
public void includeCompositeComponent(UIComponent parent, String libraryName, String resourceName, String id, Map<String, String> valueExpressions) {
...
if (!valueExpressions.isEmpty()) {
ExpressionFactory factory = application.getExpressionFactory();
ELContext ctx = context.getELContext();
for (Map.Entry<String, String> entry : valueExpressions.entrySet()) {
ValueExpression expr = factory.createValueExpression(ctx, entry.getValue(), String.class);
composite.setValueExpression(entry.getKey(), expr);
}
}
...
}
这是我的复合组件 testDatatable.xhtml:
And this is my composite component testDatatable.xhtml:
<cc:interface>
<composite:attribute name="model" required="true" type="org.primefaces.model.LazyDataModel"/>
<composite:attribute name="id" default="dataTable"/>
</cc:interface>
<cc:implementation>
<h:form id="dataTableForm">
<p:dataTable id="#{cc.attrs.id}" value="#{cc.attrs.model}" var="test" paginator="true" rows="10"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15,20" lazy="true">
<p:column>
<h:outputText value="#{test.car.model}"/>
</p:column>
</p:dataTable>
</h:form>
</cc:implementation>
这里是从支持 bean 创建复合组件:
And here is the creation of the composite component from backing bean:
Map<String, String> v = new HashMap<String, String>();
v.put("model", "#{testBean.lazyModel}");
addCompositeComponent(rootPanel, "comp", "testDatatable.xhtml", "table", v);
这是我在@PostConstruct 中加载的惰性数据模型
Here is the lazy data model I am loading in @PostConstruct
pulic class TestBean {
private TestLazyDataModel<TestClass> lazyModel;
@PostConstruct
public void init() {
lazyModel = new TestLazyDataModel();
}
public TestLazyDataModel<TestClass> getLazyModel() {
return lazyModel;
}
class TestLazyDataModel extends LazyDataModel<TestClass> {
@Override
public List<TestClass> load(int first, int pageSize, String sort, SortOrder sortOrder, Map<String, String> filters) {
List<TestClass> ret = new ArrayList<TestClass>();
TestClass t = new TestClass();
Car c = new Car("Volvo");
t.setCar(c);
ret.add(t);
return ret;
}
}
}
还有一些辅助类:
public class TestClass {
private Car car;
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
}
public class Car {
public String model;
public Car(String model) {
this.model = model;
}
public String getModel() {
return model;
}
}
总而言之,页面现在打开了:
In conclusion as the page is now opened:
- bean 创建了惰性数据模型 ok
- 从复合组件中正确获取惰性数据模型
- 当数据表尝试遍历其中的项目时,出现错误:java.lang.String"类没有属性car"
将 <h:outputText value="#{test.car.model}"/>
更改为 <h:outputText value="#{test.class.name}"/>
也是 java.lang.String 但这次没有崩溃.调试时,TestLazyDataModel 的 load() 方法不会被调用.
Changing the <h:outputText value="#{test.car.model}"/>
to <h:outputText value="#{test.class.name}"/>
also java.lang.String but does not crash this time. When debugging this the load() method of the TestLazyDataModel is never called.
更奇怪的是,如果我使用来自任何其他 xhtml 页面的相同复合组件,例如:
Also to make this even weirder is that if I use the same composite component from any other xhtml page like:
<comp:testDatatable model="#{anotherBean.model}">
它工作正常.我错过了什么?这是否与组件的渲染顺序有关?非常感谢任何帮助!
it works fine. What am I missing? Is this related somehow to the rendering order of the components? Any help is highly appreciated!
推荐答案
刚刚开始工作.. 更改复合组件值表达式包括使用 Object.class 而不是 String.class 的代码:
Just got it to work.. Changing the composite component value expression include code to use Object.class instead String.class:
public void includeCompositeComponent(UIComponent parent, String libraryName, String resourceName, String id, Map<String, String> valueExpressions) {
...
if (!valueExpressions.isEmpty()) {
ExpressionFactory factory = application.getExpressionFactory();
ELContext ctx = context.getELContext();
for (Map.Entry<String, String> entry : valueExpressions.entrySet()) {
ValueExpression expr = factory.createValueExpression(ctx, entry.getValue(), Object.class);
composite.setValueExpression(entry.getKey(), expr);
}
}
...
}
成功了.希望这对其他人也有帮助!
did the trick. Hope this helps someone else too!
这篇关于以编程方式添加的复合组件内的数据表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!