Файл тега Facelet с PrimeFaces AjaxBehavior приводит к появлению javax.el.PropertyNotFoundException: цель недоступна
Недавно я обнаружил файлы тегов Facelet в качестве альтернативы Composite Components, благодаря множеству ответов stackru, написанных BalusC, и использую их для решения проблемы с PrimeFaces dataTable. Я хочу стандартизировать кучу различных атрибутов p:dataTable в компонент / лицевую сторону, однако некоторые атрибуты, которые я хочу указать как необязательные, например, selectionMode, не могут вычислять пустую строку, в противном случае компонент не работает (см. http://forum.primefaces.org/viewtopic.php?f=3&t=29066). Используя файлы тегов Facelet и я условно представил альтернативные p:dataTables в зависимости от того, какие необязательные атрибуты присутствуют.
Однако теперь у меня появилась новая проблема с EL-выражениями AjaxBehaviors, вложенными в dataTable.
Сокращенный пример /WEB-INF/tags/dataTable.xhtml:
<ui:composition>
<p:dataTable var="row"
value="#{value}"
filteredValue="#{state.filteredValue}"
first="#{state.first}"
rows="#{state.rows}">
<f:event type="preRenderComponent" listener="#{state.onPreRenderComponent}"/>
<p:ajax event="page" listener="#{state.onPage}"/>
<p:ajax event="sort" listener="#{state.onSort}"/>
<p:ajax event="filter" listener="#{state.onFilter}"/>
<ui:insert/>
</p:dataTable>
</ui:composition>
Пример страницы с использованием файла тегов:
<my:dataTable value="#{mybean.list}" state="#{mybean.state}">
<p:column headerText="Name"
sortBy="#{row.name}"
filterBy="#{row.name}">
#{row.name}
</p:column>
</my:dataTable>
Похоже, что мои выражения "state" обрабатываются нормально до тех пор, пока не будут выполнены три события p:ajax. Событие прерывается (т. Е. Разбиение на страницы / сортировка неэффективно), и регистрируется следующая трассировка стека:
12:36:06,660 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http--0.0.0.0-8080-3) Target Unreachable, identifier 'state' resolved to null: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'state' resolved to null
at org.apache.el.parser.AstValue.getTarget(AstValue.java:98) [jbossweb-7.0.13.Final.jar:]
org.apache.el.parser.AstValue.invoke(AstValue.java:244) [jbossweb-7.0.13.Final.jar:]
org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) [jbossweb-7.0.13.Final.jar:]
org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processCustomListener(AjaxBehaviorListenerImpl.java:70) [primefaces-3.5.jar:]
org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processArgListener(AjaxBehaviorListenerImpl.java:59) [primefaces-3.5.jar:]
org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxBehaviorListenerImpl.java:47) [primefaces-3.5.jar:]
org.primefaces.event.data.SortEvent.processListener(SortEvent.java:45) [primefaces-3.5.jar:]
javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:106) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
При реализации в качестве составного компонента этой проблемы не существует, т. Е. При правильном использовании функций #{cc.attrs.state} с этими AjaxBehaviors.
Мое понимание объема и жизненного цикла файлов тегов Facelet, их атрибутов и выражений EL ограничено. Я столкнулся с ошибкой с p:ajax или мое выражение 'state' допустимо только на более ранней стадии?
К вашему сведению, объекты "mybean" и "state" используют CDI и CODI и определяются следующим образом:
@Named("mybean")
@ViewAccessScoped
@SuppressWarnings("serial")
public class MyBean implements Serializable {
private List<SomeEntiy> list;
@Inject
private DataTableState state;
public List<SomeEntity> getList() {
return list;
}
public DataTableState getState() {
return state;
}
// Details about loading the list hidden
}
...а также...
@Dependent
@SuppressWarnings("serial")
public class DataTableState implements Serializable {
private final static Logger log = Logger.getLogger(DataTableState.class.getName());
private List<?> filteredValue;
private int first;
private int rows = 20;
private Map<String,String> filters = new HashMap<String,String>();
private ValueExpression sortBy;
private String sortOrder;
public List<?> getFilteredValue() {
return filteredValue;
}
public void setFilteredValue(List<?> filteredValue) {
this.filteredValue = filteredValue;
if (filteredValue == null && !filters.isEmpty()) {
if (log.isLoggable(Level.FINEST))
log.finest("setFilteredValue: Resetting filters");
filters.clear();
}
}
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
if (log.isLoggable(Level.FINEST))
log.finest("setRows: " + rows);
this.rows = rows;
}
public Map<String,String> getFilters() {
return filters;
}
public void onPreRenderComponent(ComponentSystemEvent event) {
DataTable source = (DataTable) event.getSource();
if (sortBy != null)
source.setValueExpression("sortBy", sortBy);
if (sortOrder != null)
source.setSortOrder(sortOrder);
}
public void onPage(PageEvent event) {
DataTable source = (DataTable) event.getSource();
first = source.getFirst();
}
public void onSort(SortEvent event) {
UIColumn column = event.getSortColumn();
sortBy = column.getValueExpression("sortBy");
if (event.isAscending())
sortOrder = "ascending";
else
sortOrder = "descending";
}
public void onFilter(FilterEvent event) {
Map<String,String> filters = event.getFilters();
this.filters.clear();
this.filters.putAll(filters);
}
}