Можно ли удалить действие из commandLink после его выполнения? - PullRequest
0 голосов
/ 06 марта 2019

У меня есть таблица, и в каждой строке пользователь может щелкнуть ссылку, которая запускает проверку доступности книги. Итак, у меня есть commandLink с action, и это работает, но это действие выполняется каждый раз, когда пользователь нажимает на ссылку. Я хочу, чтобы он был доступен только один раз. Также я не хочу скрывать ссылку после клика, так как она имеет код onclick, который скрывает и показывает детали. Можно ли удалить action из командной строки после выполнения действия?

1 Ответ

0 голосов
/ 07 марта 2019

Ответ покрыт Можно ли использовать условный оператор EL в атрибуте действия? - это один из способов решения этой проблемы. При этом, начиная с выпуска JSF 2.2 , есть и другие альтернативы. Хотя удаление атрибута действия в JSF проблематично (это можно сделать с помощью некоторых хитростей) - другое решение заключается в использовании actionListeners вместе с привязкой f:event, которая связана с событием preValidate. Это позволяет вам удалить любой из подключенных actionListener, когда вы решите это сделать.

Вот полное решение с прослушивателем событий, который изменяет компонент до его обработки для представления. По сути, вы можете сделать что-то вроде этого;

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Dynamic action demo</title>
    </h:head>
    <h:body>
        <h:form>
            <h:dataTable var="row" value="#{removeActionBackingBean.rows}">
                <h:column>#{row.primaryColumn}</h:column>
                <h:column>#{row.hasBeenClicked}</h:column>
                <h:column>
                    <h:commandButton actionListener="#{removeActionBackingBean.onPressed(row)}">
                        <f:attribute name="clicked" value="#{row.hasBeenClicked}"/>
                        <f:event listener="#{removeActionBackingBean.onModify}" type="preValidate" />
                        <f:ajax event="click" render="@form" />
                    </h:commandButton>
                </h:column>
            </h:dataTable>
        </h:form>
    </h:body>
</html>

Для базового компонента приведено решение с полной моделью (с использованием Lombok);

@Data
@Named
@ViewScoped
public class RemoveActionBackingBean implements Serializable {
    private List<Row> rows;

    @PostConstruct
    private void init() {
         rows = new ArrayList<>();

         for (int i = 0; i < 10; i++) {
             rows.add(new Row(RandomStringUtils.randomAscii(10)));
         }
    }

    public void onPressed(Row row) {
        row.hasBeenClicked = true;
        System.out.println(String.format("'%s' has been pressed!", row.primaryColumn));
    }

    public void onModify(ComponentSystemEvent event) {
        final boolean isRowClicked = (boolean) event.getComponent().getAttributes().get("clicked");

        if (isRowClicked) {
            for (ActionListener al : ((UICommand) event.getComponent()).getActionListeners()) {
                ((UICommand) event.getComponent()).removeActionListener(al);
            }
        }
    }

    @Data
    @RequiredArgsConstructor
    public class Row {
        private @NonNull String primaryColumn;
        private boolean hasBeenClicked;
    }
}

Ключевые разделы, на которые следует обратить внимание: f:event и привязка метода onModify(). Как видите, мы просто проверяем, считается ли определенная «строка» нажатой - если это так, мы очищаем все actionListener, определенные в данный момент для компонента. По сути, при нажатии кнопки не будет вызываться actionEvent.

Хотя вышеприведенное решение изменяет actionListeners кнопки, оно может быть принято и использовано для других типов компонентов, а также когда вы хотите изменить определенные атрибуты компонента на основе какого-либо условия - поэтому очень полезно знать этот прием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...