Не удается заставить MenuItem вызывать его ActionListeners - PullRequest
2 голосов
/ 10 февраля 2012

Я пытаюсь заставить Primefaces MenuItem [в пределах Menubar] испускать ActionEvent и вызывать метод при нажатии, однако методы прослушивания никогда не вызываются, и я понятия не имею, почему:

xhtml page:

<h:body>
<h:form>
    <p:menubar model="#{testBean.model}" />
    <h:commandButton value="submit" />
    <h:outputText value="#{testBean.confirmation}" />
</h:form>
</h:body>
</html>

jsf bean:

@ManagedBean
public class TestBean implements ActionListener{

    MenuModel model = new DefaultMenuModel();
    private String confirmation = "negative";

    public TestBean() {
        MenuItem item = new MenuItem();
        item.setValue("Click");
        item.setUrl("#");
        item.addActionListener(this);
        model.addMenuItem(item);
    }

    @Override
    public void processAction(ActionEvent event)
            throws AbortProcessingException {

        // EXECUTION NEVER REACHES HERE!
        confirmation = "positive";
    }

    public MenuModel getModel() {
        return model;
    }

    public String getConfirmation() {
        return confirmation;
    }
}

Это может помочь визуализировать очень простой вывод:

enter image description here

Я использую Primefaces 3.1.0 и JSF 2.0

Ответы [ 4 ]

3 голосов
/ 10 февраля 2012

Мое первое предложение состоит в том, чтобы добавить какую-либо запись отладки в ваш слушатель действия, чтобы выяснить, вызван он или нет. Если он вызывается, но ваш сайт не отображает изменения, это может быть вызвано следующими причинами.

  • Слушатель действия не запускает обновление DOM на стороне клиента.
  • Кнопка отправки запускает запрос. Управляемый bean-компонент извлекается и повторно инициализируется со значениями по умолчанию, поскольку он управляется в области запроса. Вы должны попытаться поместить свой бин в управление @ViewScoped или @SessionScoped.

Кстати, мы не реализуем ActionListener. Мы присваиваем выражения метода пунктам меню. Вот краткий пример макета: мы использовали действие элемента меню, чтобы переключать состояния кнопок контекстного меню. Надеюсь, я смогу тебе как-нибудь помочь.

Фрагмент Facelet:

<p:menu model="#{menuBean.model}" />

Фрагмент боба:

@ManagedBean
@ViewScoped
public class MenuBean implements Serializable {

    private MenuModel model;
    private boolean cutAllowed = false;

    /** Creates a new instance of MenuBean */
    public MenuBean() {
        model = new DefaultMenuModel();

        //First submenu
        Submenu submenu = new Submenu();
        submenu.setLabel("Dynamic Submenu 1");

        MenuItem item = new MenuItem();
        item.setValue("toggle");
        item.setUpdate("contextMenu");
        item.setAjax(true);
        item.setIcon("ui-icon ui-icon-disk");
        ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
        MethodExpression methodExpression = factory.createMethodExpression(FacesContext.getCurrentInstance().getELContext(), "#{menuBean.toggleCutState}", String.class, new Class[]{});

        item.setActionExpression(methodExpression);

        submenu.getChildren().add(item);

        model.addSubmenu(submenu);
    }

    public boolean isCutAllowed() {
        return cutAllowed;
    }

    public void setCutAllowed(boolean cutAllowed) {
        this.cutAllowed = cutAllowed;
    }

    public String toggleCutState() {
        toggleCutState(null);
        return null;
    }

    public void toggleCutState(ActionEvent event) {
        this.cutAllowed = !this.cutAllowed;
        System.out.println("toggle called");
    }       

    public MenuModel getModel() {
        return model;
    }  
}
1 голос
/ 12 января 2013

@ Mogwli, item.setId ((новый UiViewRoot ()). CreateUniqueId ()); вызовет IllegalArgumentException, так как новый UIViewRoot () не будет контекстно-зависимым ... Должен был item.setId (FacesContext.getCurrentInstance (). getViewRoot (). createUniqueId ());

1 голос
/ 14 февраля 2012

Первая проблема с исходным кодом заключалась в том, что мне был нужен уникальный идентификатор. Я обнаружил это на ранних этапах, но это привело к другим очень раздражающим проблемам: вызывался слушатель действия, но страница не обновлялась. Чтобы решить эту проблему (как описано здесь ), вы либо отключаете ajax в MenuItem, либо настраиваете его обновление.

Правильный код конструктора:

public TestBean() {
    MenuItem item = new MenuItem();
    item.setValue("Click");

    // New code:
    item.setId(FacesContext.getCurrentInstance().getViewRoot().createUniqueId());
    item.setAjax(false);

    item.setUrl("#");
    item.addActionListener(this);
    model.addMenuItem(item);
}
0 голосов
/ 10 февраля 2012

Прежде всего, ваш фрагмент кода показывает <h:commandButton>, который является , а не кнопкой Primefaces command * Кнопка 100 * *

Во-вторых, вы не указываете атрибут actionListener команды commandButton для указания на processAction.

<p:commandButton value="submit" actionListener="#{testBean.processAction}" /> 
...