3 каскадных выпадающих меню с Ajax - PullRequest
2 голосов
/ 25 ноября 2011

Я хочу изменить пример "ajaxify select" в демонстрационном приложении PrimeFaces и ввести третий p:selectOneMenu с вариантами выбора в зависимости от выбора второй p:selectOneMenu.

Вотмодифицированный код:

<h:form>  
    <p:growl id="msgs" showDetail="true"/>  
    <p:panel header="Double Combo" style="margin-bottom:10px;">  
        <h:panelGrid columns="3" cellpadding="5">  
            <p:selectOneMenu id="city" value="#{pprBean.city}">  
                <f:selectItem itemLabel="Select City" itemValue="" />  
                <f:selectItems value="#{pprBean.cities}" />  
                <p:ajax update="suburbs"  
                        listener="#{pprBean.handleCityChange}" />  
            </p:selectOneMenu>  

            <p:selectOneMenu id="suburbs" value="#{pprBean.suburb}">  
                <f:selectItem itemLabel="Select Suburb" itemValue="" />  
                <f:selectItems value="#{pprBean.suburbs}" />  
                <p:ajax update="subsuburbs"  
                    listener="#{pprBean.handleSuburbChange}" />  
            </p:selectOneMenu>  

            <p:selectOneMenu id="subsuburbs" value="#{pprBean.subsuburb}">  
                <f:selectItem itemLabel="Select Subsuburb" itemValue="" />  
                <f:selectItems value="#{pprBean.subsuburbs}" />  
            </p:selectOneMenu>  
        </h:panelGrid>  

        <p:separator />  

        <p:commandButton value="Submit" update="msgs" 
            actionListener="#{pprBean.displayLocation}"/>  
    </p:panel>  
</h:form> 

Но функция слушателя #{pprBean.handleSuburbChange} никогда не выполняется.На другом форуме я видел, что динамический код в ответе ajax не включает тег, отличный от тега, указанного в атрибуте обновления, но как я могу это сделать?

В PPRBean код, который я добавил:

@Named("pprBean")
@RequestScoped
public class PPRBean implements Serializable {

    // ...

    public void handleSuburbChange() {
        if (suburb != null && !suburb.equals("")) {
            subsuburbs = subsuburbsData.get(suburb);
        } else {
            subsuburbs = new HashMap<String, String>();
        }
        log.info("subsuburbs:" + subsuburbs);
    }

    // ...

1 Ответ

0 голосов
/ 25 ноября 2011

Слушатель не будет вызван, если выбранный элемент не может быть обработан. Вы поместили bean-компонент в область запроса, что означает, что он будет обработан после завершения ответа, связанного с запросом (т. Е. Когда браузер завершит загрузку страницы). Поэтому, когда вы отправляете форму, будет запущен новый запрос и создан новый компонент, который, по-видимому, в вашем случае не подготавливает / не заполняет список пригородов в конструкторе (post), чтобы найти выбранный элемент ( и исполнить слушателя).

Чтобы исправить это, обычно нужно поместить компонент в область видимости с помощью аннотации JSF @ViewScoped вместе с @ManagedBean.

@ManagedBean
@ViewScoped
public class Bean {
    // ...
}

Таким образом, экземпляр компонента будет жить, пока вы взаимодействуете с одним и тем же представлением. Но так как вы используете CDI для управления bean-компонентами вместо JSF, вам нужно будет использовать @ConversationScoped вместо этого и контролировать Conversation самостоятельно.

@Named
@ConversationScoped
public class Bean {

    @Inject
    private Conversation conversation;

    @PostConstruct
    public void init() {
        conversation.begin();
        // ...
    }

    public void submit() {
        // ...
        conversation.end();
    }

}
...