Вопрос по primefaces, jsf-2, jsf, ajax – Можете ли вы обновить h: outputLabel из прослушивателя p: ajax?

4

Я пытаюсь использовать тег p: ajax, а затем в этом слушателе я устанавливаю значение с именем «periodRendered». затем я пытаюсь обновить тег h: outputLabel с помощью обновления тега p: ajax. Он не обновляет ajaxily, и я думаю, что это потому, что тег ajax primefaces не может обновить стандартный тег jsf outputLabel.

Правильно ли мое предположение и есть ли более подходящий тег, который я должен использовать вместо h: outputLabel?

<code><h:outputLabel for="addProgramTo" value="Add Program To" />
<p:selectOneMenu value="#{ppBacker.grantProgram.grant_project_id}" id="addProgramTo" size="1" styleClass="listBoxMedium">
    <p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabel" event="change" listener="#{ppBacker.addProgramListener}" />
    <f:selectItems value="#{ppBacker.grantProjectDropDownList}" />
</p:selectOneMenu>            

<h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}"> 
</code>

Ваш Ответ

2   ответа
10

rendered=false "это способ JSF" для удаления элементов из дерева DOM,

это не как CSSdisplay:none илиvisibility:hidden <- эти два элемента будут хранить элементы в дереве DOM, но скрыты, а JSFrendered=false не будет даже отображать (сохранять) элемент в дереве DOM (вы даже не увидите его в «источнике представления» страницы)

Так что в этом случае вам нужно обернутьoutputLabel с помощью `panelGroup 'и обновите идентификатор оболочки

<h:panelGroup id="periodLabelWrapper">
    <h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}">
</h:panelGroup>

и ссылаются на идентификатор оболочки (который всегда находится в дереве DOM) в<p:ajax update атрибут, как это:

<p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabelWrapper" event="change" listener="#{ppBacker.addProgramListener}" />

Другим решением было бы обновить всю форму, как эта<p:ajax update="@form" ... таким образом, вам не нужно обертываниеoutputLabel

учитывая ваш комментарий к вопросу

Как @form обновляет не визуализированные элементы, но нацеливание на них напрямую через идентификаторы не делает?

Ты не можешь нацелиться на элемент вupdate которого нет на странице (rendered = false) "его там нет"

Но когда вы используетеupdate="@form" илиupdate="someWrapperID" форма / обертка "переоценивает" все ее внутренние элементы, в том числе сrendered="#{someBean.someCondition}" и условие переоценивается, так что если оно приводит кtrue Элемент будет отображаться ...

primefaces также предоставляет панель обновления для этого djmj
тоже не видел ... Daniel
@ djmj Как называется панель простых лиц? Я не вижу "updatePanel" - Primefaces.org / витрина-лаб / щ / panel.jsf Catfish
обновил мой ответ Daniel
Как @form обновляет не визуализированные элементы, но нацеливание на них напрямую через идентификаторы не делает? Catfish
1

но я вкладываю деньги в тот факт, что p: ajax будет требовать активную цель для обновления. Вот пример того, как это работает / не работает:

<h:body styleClass="center">
    <f:view contentType="text/html">
        <h:form id="test">
            <h:outputLabel for="addProgramTo" value="Add Program To: " />
            <h:selectOneMenu id="addProgramTo" value="#{testScope.target}">
            <p:ajax update=":test:periodLabel, :test:wrapper" event="change" process="@form">
            </p:ajax>
            <f:selectItems value="#{testScope.values}"/>
            </h:selectOneMenu>            
            <hr />
            <p:outputPanel id="wrapper">
                <h:outputLabel value="Works, has a target" rendered="#{testScope.timeToRender}"/>
            </p:outputPanel>
            <hr />
            <h:outputLabel value="does not work" id="periodLabel" rendered="#{testScope.timeToRender}" />   
        </h:form>
    </f:view>

</h:body>

// Bean ...

@ViewScoped
@ManagedBean(name = "testScope")
public class TestScope
{
    private String[] values = { "False", "What?", "True" };
    private String target = "Nothing";

    /**
     * @return the target
     */
    public String getTarget()
    {
        return target;
    }

    /**
     * @return the values
     */
    public String[] getValues()
    {
        System.out.println(values);
        return values;
    }

    public boolean isTimeToRender()
    {
        return "True".equals(target);
    }

    /**
     * @param target the target to set
     */
    public void setTarget(String target)
    {
        this.target = target;
    }
}

У меня нет времени копаться в этом, но при быстром взгляде (снова БЫСТРО) в отладчике кажется, что он не находит идентификатор (он не отображается), поэтому он не получает Обновить. Зачем? Я не уверен - простой обходной путь - поместить его внутри чего-то, что вы можете обновить (p: outputPanel), и отобразить его как span, тогда ваш код должен работать. Это приемлемо? На самом деле, нет..

Если вы можете справиться с полным обновлением формы, то будет работать и следующее ->

<p:ajax update=":test" event="change" process="@form">

Так как вы нацелены на вложенную форму, она обновляет всех детей. Если бы я делал это, я бы использовал этот обходной путь. Это не много данных, и это чертовски много чище. Я не уверен, если это ошибка или особенность. Хотя он чувствует себя глючным.

Короткий ответ: да, вы можете настроить таргетинг на ярлык. Длинный ответ: вы не можете выбрать цель, которая не отображается. Я действительно надеюсь, что это поможет.

Похожие вопросы