Помогите разобраться с поведением bean-компонента ‹h:commandLink›/‹h:dataTable›/request?

Я пытаюсь решить хорошо известную «проблему», когда метод действия h: commandLink не вызывается при помещении в dataTable, который получает свои данные из bean-компонента с областью запроса. Из-за ограничений проекта я ограничен использованием JSF 2.0 и RichFaces 3.x (который частично его поддерживает), поэтому я не могу полагаться на решение Tomahawk (preserveDataModel).

После дня, потраченного на поиски и пробы/ошибки:

  • Я читал, что «модель данных», которую использует dataTable, должна храниться в сеансе. Как я могу это сделать, не превращая весь компонент в область сеанса? Я пробовал со статической переменной, которая содержит данные, но не работает.
  • Я пытался использовать a4j:keepAlive с моим bean-компонентом (который реализует Serializable, если это имеет значение), но не смог заставить его работать.
  • Создание bean-компонента ViewScoped также не работает.

Любая помощь относительно этого будет оценена по достоинству.

РЕДАКТИРОВАТЬ:

Вот что я пытаюсь сделать:

На странице есть комбинация, отображающая ряд параметров, извлеченных из базы данных. Когда пользователь выбирает один, dataTable заполняется информацией, связанной с выбранным параметром. Данные первого столбца отображаются в виде командных ссылок. Если пользователь щелкает ссылку, он должен вызывать указанный метод, но он не вызывается.

моя страница.xhtml

<h:form>
<!-- Placed a <a4j:keepAlive beanName="myBean"> in this line, but didn't work -->
<h:selectOneMenu value="#{myBean.selectedOption}">
    <f:selectItems value="#{myBean.optionsList}" var="option"
                   itemLabel="#{option.labelProperty}" itemValue="#{option.valueProperty}"/>
    <a4j:support event="onchange" action="#{myBean.getDataBasedOnSelectedOption}"
        reRender="table_panel" ajaxSingle="true"/>
</h:selectOneMenu>

<a4j:outputPanel id="table_panel" >
    <rich:dataTable id="table" value="#{myBean.data}" var="dataRow"
             rendered="#{not empty myBean.selectedOption}">
        <f:facet name="header">
            <rich:columnGroup>
                <rich:column>Some column header</rich:column>
            </rich:columnGroup>
        </f:facet>

        <rich:column>
                <a4j:commandLink  action="#{myBean.linkClickedAction}"
                    value="#{dataRow.someProperty}"/>
        </rich:column>
</a4j:outputPanel>

MyBean.java

@ManagedBean(name="myBean")
@RequestScoped //Tried with @ViewScoped but didn't work

private List<MyPOJO1> optionsList;
private List<MyPOJO2> data; //Made this variable static, but didn't work
private String selectedOption;

@PostConstruct
public void init()
{
    optionsList = getOptionsListFromDatabase();
}

public String getDataBasedOnSelectedOption()
{
    data = getRelevantDataFromDatabase(selectedOption);

    return null;
}

//This method doesn't get called
public String linkClickedAction()
{
    System.out.println("I'm here!");

    return null;
}

public List<MyPOJO1> getOptionsList()
{
   return optionsList;
}

public void getSelectedOption()
{
    return selectedOption;
}

public void setSelectedOption(String selectedOption)
{
    this.selectedOption = selectedOption;
}

person etercap    schedule 03.12.2010    source источник
comment
Использование области просмотра или ‹a4j:keepAlive› должно работать. Не могли бы вы написать более подробно, как вы это пробовали?   -  person chkal    schedule 04.12.2010


Ответы (1)


Если a4j:keepAlive или @ViewScoped не работают, велика вероятность, что логика загрузки данных для модели данных неверна. Вероятно, вы загружаете его внутри геттера на основе некоторых параметров, а не в методе действия, конструкторе или @PostConstruct компонента. Геттер также будет вызываться на этапе применения значений запроса жизненного цикла JSF, чтобы определить строку, в которой нажата командная ссылка, чтобы JSF мог определить, какое действие необходимо вызвать. Если геттер не возвращает модель данных с ожидаемой строкой, то действие просто не будет вызвано.

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

person BalusC    schedule 04.12.2010