【问题标题】:Datatable inside programatically added composite component以编程方式添加的复合组件内的数据表
【发布时间】:2013-04-09 23:15:09
【问题描述】:

参考我之前的问题 (Programmatically create and add composite component in backing bean),我已经成功地能够从支持 bean 添加复合组件。现在我有一个新问题,因为其中包含惰性数据表的复合组件根本不调用 load() 方法。有关于此的错误报告 (https://code.google.com/p/primefaces/issues/detail?id=3258) 但被标记为与 PF3.0.RC1 相关,我不知道它是否已针对我正在使用的 3.5 版本修复。

我正在使用完全相同的代码 BalusC,可以将值表达式添加到复合组件:

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:

<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>

下面是从 backing bean 创建复合组件:

Map<String, String> v = new HashMap<String, String>();
v.put("model", "#{testBean.lazyModel}");
addCompositeComponent(rootPanel, "comp", "testDatatable.xhtml", "table", v);

这是我在@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;
    } 
}

总之,页面现在打开了:

  1. bean 创建惰性数据模型 ok
  2. 从复合组件中正确获取惰性数据模型
  3. 当数据表尝试遍历其中的项目时,出现错误:“java.lang.String”类没有“car”属性

&lt;h:outputText value="#{test.car.model}"/&gt; 更改为 &lt;h:outputText value="#{test.class.name}"/&gt; 也是 java.lang.String 但这次不会崩溃。调试时,永远不会调用 TestLazyDataModel 的 load() 方法。

让这更奇怪的是,如果我使用来自任何其他 xhtml 页面的相同复合组件,例如:

<comp:testDatatable model="#{anotherBean.model}"> 

它工作正常。我错过了什么?这是否与组件的渲染顺序有关?非常感谢任何帮助!

【问题讨论】:

    标签: dynamic jsf-2 primefaces facelets composite-component


    【解决方案1】:

    刚刚开始工作.. 更改复合组件值表达式包含代码以使用 Object.class 而不是 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);
            }
        } 
        ...
    }
    

    成功了。希望这对其他人也有帮助!

    【讨论】:

      猜你喜欢
      • 2014-08-16
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 2018-08-25
      • 2011-05-02
      • 1970-01-01
      • 2017-01-29
      相关资源
      最近更新 更多