JSF2: action и actionListener - PullRequest
       39

JSF2: action и actionListener

2 голосов
/ 30 декабря 2011

Из этого ответа BalusC здесь Различия между action и actionListener , Use actionListener if you want have a hook before the real business action get executed, e.g. to log it, and/or to set an additional property (by <f:setPropertyActionListener>,.Однако, когда я решаю написать некоторый код, чтобы проверить это, результат немного отличается.Вот мой маленький код

<h:form id="form"> 
   <h:panelGroup id="mygroup">
     <p:dataTable id="mytable" value="#{viewBean.foodList}" var="item">
         <p:column>
             #{item}
         </p:column>
         <p:column>
             <p:commandButton value="delete" 
                        action="#{viewBean.delete}"
                        update=":form:mygroup">
                 <f:setPropertyActionListener target="#{viewBean.selectedFood}"
                                              value="#{item}"/>
             </p:commandButton>
         </p:column>
      </p:dataTable>
   </h:panelGroup>
</h:form>

Вот мой боб

@ManagedBean
@ViewScoped
public class ViewBean {
    private List<String> foodList;
    private String selectedFood;

    @PostConstruct
    public void init(){

        foodList = new ArrayList<String>();
        foodList.add("Pizza");
        foodList.add("Pasta");
        foodList.add("Hamburger");
    }

    public void delete(){
        foodList.remove(selectedFood);
    }
    //setter, getter...
}

Согласно BalusC, actionListener здесь больше подходит здесь, но мой пример показывает в противном случае .

Приведенный выше код прекрасно работает с action, но если я переключусь на actionListener, то он не совсем работает.Мне понадобится два клика , чтобы удалить запись в этой таблице, используя actionListener, а если я использую action, она удалит запись каждый раз, когда я нажимаю кнопку.Интересно, сможет ли какой-нибудь эксперт JSF помочь мне понять action против actionListener

Примечание Если я переключусь на actionListener, мой delete метод станет public void delete(ActionEvent actionEvent)

Ответы [ 2 ]

16 голосов
/ 01 января 2012

Вы путаете action с actionListener.actionListener всегда работает до action.Если имеется несколько прослушивателей действий, они запускаются в том же порядке, в котором они были зарегистрированы.Вот почему он не работает должным образом, когда вы используете actionListener для вызова бизнес-действия и <f:setPropertyActionListener> для установки (подготовки) свойства, которое будет использоваться бизнес-действием.Эта проблема была указана и исправлена ​​в вашем предыдущем вопросе Это ошибка Primefaces или ошибка Mojarra / MyFaces .

Все, что у вас есть в методе delete(), явно является бизнес-действием и должно бытьвместо этого вызывается action.Бизнес-действие обычно вызывает службу EJB и, если необходимо, также устанавливает конечный результат и / или перемещается в другое представление.

4 голосов
/ 31 декабря 2011

Я попробовал ваш пример с оригинальными тегами JSF <h:commandButton>, но у меня также есть тот же симптом. Я полагаю, что если вы укажете атрибут actionListener и в то же время объявите другого слушателя с <f:setPropertyActionListener>, слушатель в атрибуте actionListener будет запущен раньше другого.

ОБНОВЛЕНИЕ : я проверяю свое предположение с помощью следующего кода:

  • Измените вашу delete функцию на эту:

    public void delete(){
        this.selectedFood = "Chicken";
        //foodList.remove(selectedFood);
    }
    
  • Добавить <h:outputText id="food" value="#{viewBean.selectedFood}" /> внутри <h:panelGroup id="mygroup">.

Вы увидите, что outputText всегда равен Chicken.

...