Почему я могу связать <f: actionListener> с произвольным методом, если он не поддерживается JSF?
Я использую Glassfish 3.1.2.2 и JSF Mojarra 2.1.6.
У меня есть следующая страница Facelets:
<h:form>
<h:commandLink value="link">
<f:actionListener binding="#{backingBean.someMethod(1)}"/>
</h:commandLink>
</h:form>
И следующий боб:
@RequestScoped
@ManagedBean
public class BackingBean {
public void someMethod(int i) {
System.out.println("It was called: " + i);
}
}
Когда я нажимаю на ссылку, в консоли появляется "Информация: она была вызвана: 1".
Документация для binding
гласит:
Библиотека: http://xmlns.jcp.org/jsf/core, http://java.sun.com/jsf/core (Jsf Core)
Tag: actionListener
переплет
Выражение привязки значения, которое оценивает объект, который реализует javax.faces.event.ActionListener. [акцент мой]
Кроме того, принятый ответ на этот вопрос гласит, что это невозможно для f:actionListener
вызвать произвольный метод.
Почему вызывается метод резервного компонента, если он не поддерживается?
1 ответ
Это является следствием новой возможности EL 2.2 - вызова метода в выражении значения через #{bean.method()}
синтаксис вместо ссылки на свойство только через #{bean.property}
синтаксис (который действительно должен быть точного типа ActionListener
). Это не сработало бы в EL 2.1 и более ранних версиях, а также не работало бы, когда вы удаляете аргументы и скобки. Этот документ был написан, когда EL 2.2 не существовало (на самом деле он не был изменен по сравнению с версией JSF 1.2 с мая 2006 года; EL 2.2 был представлен в декабре 2009 года). Тем не менее, я согласен с тем, что он нуждается в обновлении в этой части, поскольку это вводит в заблуждение начинающих.
Ответ, который вы нашли, основывался на документе, но ответчик, похоже, не осознавал этого вопроса, binding="#{testController.nodeListener}"
не удалось binding="#{testController.nodeListener(event)}"
на самом деле работал. Это только не дает вам возможность пройти ActionEvent
, Ответ был бы лучше, если бы он предложил просто использовать binding="#{testController.nodeListener()}"
вместо этого и получить информацию о событии другим способом, например, позвонив UIComponent#getCurrentComponent()
или даже мимоходом #{component}
в качестве аргумента. Конечно, только если вам действительно нужна рука.
<h:commandLink value="link">
<f:actionListener binding="#{bean.someMethod(component)}"/>
</h:commandLink>
public void someMethod(UIComponent component) {
System.out.println("It was called on: " + component); // HtmlCommandLink
}