Как я получаю значение компонента JSF при помощи EL?

Перед продолжением посмотрите этот вопрос

Это - форма JSF, показан снова следующим образом:


    
        

Заметьте, что я использовал вместо . Для получения его значения при помощи Шва сопоставитель EL я использую param.amount.

Это происходит это, если я использую и что-то идет не так, как надо на стороне сервера, я должен показать страницу снова. Таким образом, его отправленное значение не получено, потому что это - простой HTML-код. Из-за этого я должен использовать a Компонент JSF вместо этого.

Таким образом, вопрос: Как я получаю a Значение компонента JSF при помощи Языка Выражения?

8
задан Community 23 May 2017 в 11:53
поделиться

3 ответа

Идентификаторы клиента JSF добавляются идентификатором клиента родительского компонента UINamingContainer (например, h: form , h: dataTable , f: subview ). Если вы проверите сгенерированный источник HTML в своем веб-браузере (щелкните правой кнопкой мыши, просмотреть исходный код), тогда вы должны их увидеть. К id и name сгенерированных входных элементов добавляется id родительской формы. Вам нужно использовать то же имя, что и ключ в карте параметров. В качестве разделительного символа двоеточие : является «недопустимым» символом в EL, вам нужно использовать скобку param ['foo: bar'] для их получения.

<f:view>
    <h:form id="account">
        <div>
            <label>Id</label>
            <h:inputText id="id" />
        </div>
        <div>
            <label>Amount</label>
            <h:inputText id="amount" />
        </div>
        <h:commandButton value="Withdraw" 
            action="#{accountService.withdraw(param['account:id'], param['account:amount'])}"/>
    </h:form>
</f:view>

Без параметров метода типа Seam-EL (вы, очевидно, не хотите / не имеете), вы также можете получить к ним доступ в карте параметров запроса, используя идентификаторы клиента в качестве ключей:

public void withDraw() {
    Map<String, String> map = FacesContext.getCurrentInstance().getRequestParameterMap();
    String id = map.get("account:id");
    String amount = map.get("account:amount");
    // ...
}

Само собой разумеется, что это неприятно. Просто сделайте это обычным способом JSF, свяжите значения со свойствами bean.

Edit: в соответствии с последним вопросом, который вы отредактировали:

Итак, вопрос: как мне получить < час: inputText Значение компонента JSF с использованием языка выражений?

Ответ на этот вопрос уже был дан ранее. Используйте имя , созданное JSF, в качестве имени параметра. Обычно это шаблон formId: inputId , где formId - это id родительского компонента UIForm и входной идентификатор - это идентификатор компонента UIInput . Проверьте сгенерированный вывод HTML на предмет точного имени созданного поля . Чтобы получить значение параметра, используйте обозначение скобок ['name'] , потому что вы не можете использовать двоеточие : в EL, как в $ {param.formId: inputId} .

Таким образом:

#{param['formId:inputId']}
18
ответ дан 5 December 2019 в 08:52
поделиться

Имена / идентификаторы параметров для inputText инкапсулируются средством визуализации управления и, в конечном счете, являются деталью реализации. На практике они используют clientId . Нет необходимости читать их прямо из карты параметров; используйте привязку значений, чтобы протолкнуть их в модель и прочитать оттуда.

Вы можете считывать значения непосредственно из компонента с помощью EL, привязав компонент к управляемому bean-компоненту. Для простоты здесь один привязан к области запроса:

<!-- bind a UIComponent to the request map as "foo" -->
<h:inputText binding="#{requestScope.foo}" />
<!-- read value from a UIComponent that implements ValueHolder -->
#{requestScope.foo.value}

Но, как правило, у этого нет преимущества перед:

<!-- bind a value to the request map as "foo" -->
<h:inputText value="#{requestScope.foo}" />
<!-- read value from the request scope -->
#{requestScope.foo}

Чтобы избежать загрязнения карты запроса (что может привести к конфликтам между представлениями), используйте управляемый компонент для пространство имен / инкапсулируйте ваши значения вместо прямого использования области запроса.

1
ответ дан 5 December 2019 в 08:52
поделиться

Хотя я могу получить значение JSF компонента через его идентификатор клиента, но есть некоторые недостатки:

  1. Согласно ответу McDowell, идентификатор клиента является реализационной деталью
  2. Идентификатор клиента может отличаться от идентификатора компонента, когда в иерархии управления присутствует более одного контейнера именования. (JSF в книге действий)

Так что если вы не хотите полагаться на идентификатор клиента, вы можете реализовать свой собственный ElResolver следующим образом:

public class ComponentIdResolver extends ELResolver {

    public Object getValue(ELContext context, Object base, Object property) {
        if (base instanceof UIComponent && property instanceof String) {
            UIComponent r = ((UIComponent) base).findComponent((String) property);

            if (r != null) {
                context.setPropertyResolved(true);

                return r;
            }
        }

        return null;
    }

}

Теперь я могу использовать что-то вроде (Notice withdraw method)

<h:inputText id="accountId" />
<h:inputText id="amount" />
<h:commandButton value="Withdraw" action="#{accountService.withdraw(view.accountId.value, view.amount.value)}"/>

view - это неявный JSF объект (похожий на FacesContext.getCurrentInstance(). getViewRoot())

Затем зарегистрируйте свой ELResolver, как показано ниже (faces-config.xml)

<application>
    <el-resolver>br.com.view.resolver.ComponentIdResolver</el-resolver>
</application>

Если вы хотите узнать хорошее представление об ElResolver, смотрите Расширение Java EE Unified Expression Language с помощью пользовательского ELResolver

regard,

.
0
ответ дан 5 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

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