2013-04-17 2 views
1

Ссылаясь на мой более ранний вопрос (Programmatically create and add composite component in backing bean), я успешно смогу добавить составные компоненты из бэк-компонента. Теперь у меня есть новая проблема, поскольку составной компонент с ленивым datatable в нем вообще не вызывает метод load(). Об этом было сообщено об ошибке (https://code.google.com/p/primefaces/issues/detail?id=3258), но это помечено как связанное с PF3.0.RC1, и я не знаю, если он исправлен для версии 3.5, которую я использую.Datatable внутри программно добавленного композитного компонента

Я использую точно такой же код 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> 

И здесь является создание композитного компонента из бэк-бобов:

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. боб создает модель ленивых данных ok
  2. Ленточная модель данных правильно выбрана из композитного компонента
  3. Когда DataTable пытается Переберите элементы в нем ошибки: Класс «java.lang.String» не имеет свойство «автомобиль»

, изменяющих <h:outputText value="#{test.car.model}"/> к <h:outputText value="#{test.class.name}"/> также java.lang.String но не рухнет на этот раз. При отладке этого метода load() TestLazyDataModel никогда не вызывается.

Кроме того, чтобы сделать это еще страннее, что если я использую тот же составной компонент любого другого Xhtml страницы, как:

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

он работает отлично. Что мне не хватает? Связано ли это с порядком рендеринга компонентов? Любая помощь высоко ценится!

ответ

3

Просто получил его на работу .. Изменения выражения составного значения компоненты включает в себя код, чтобы использовать 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); 
     } 
    } 
    ... 
} 

сделал трюк. Надеюсь, это тоже поможет кому-то!