Параметры JSF 1.1 в скрытом поле

Моя цель — передать строку с параметрами (Hello {0}) из вспомогательного компонента в JavaScript. Мой текущий подход заключается в том, чтобы поместить строку в h:inputHidden и позволить JS прочитать значение onLoad. К сожалению, f:param внутри h:inputHidden не работает, как в h:outputFormat.

Какой подход вообще рекомендуется?

  • Я мог бы объединить строку с параметрами в поддерживающем bean-компоненте, но imo это не должно касаться bean-компонентов.
  • Я мог бы объединить их в JS, но опять же это похоже на изобретение велосипеда (используя replace функций...)
  • Я не вижу (хорошего) способа использовать h:outputFormat, но сделать его невидимым для пользователя.
  • Я не вижу способа заставить h:inputHidden принять f:param.

EDIT: Реальная используемая реализация — Apache MyFaces 1.1.4, поэтому я обновил заголовок до JSF 1.1.

Из-за ответа BalusC я вспомнил свой первый (и отброшенный) подход:

  • Прямое включение в исходный код JS.

    <script>
        var text = '<h:outputFormat value="Hello {0}"><f:param value="World" /></h:outputFormat>';
    </script>
    

К сожалению, в JSF 1.1 мне приходится использовать <f:verbatim>, что делает код действительно уродливым (даже программа проверки синтаксиса eclipses не понимает его, хотя он работает):

<f:verbatim>
    <script>
        var text = '</f:verbatim>
<h:outputFormat value="Hello {0}"><f:param value="World" /></h:outputFormat>
<f:verbatim>';
        </script>
</f:verbatim>

И дополнительный недостаток в том, что я не могу поместить это в <head>, так как оно должно быть внутри <f:view>.


person SebastianH    schedule 10.02.2014    source источник
comment
@BalusC, @LaurentG: Спасибо вам обоим за ваши комментарии. Я приму ответ LautentG, потому что это также мой предпочтительный подход. Как уже упоминалось в моем вопросе, подход <f:verbatim> действительно уродлив. Я присуждаю награду BalusC за все время, которое он потратил на свои ответы и комментарии, которые мне очень помогли :)   -  person SebastianH    schedule 14.02.2014
comment
Спасибо. Я бы хотел получить свою первую награду, но я должен согласиться, что ответы balusC всегда самые лучшие!   -  person LaurentG    schedule 14.02.2014


Ответы (2)


Поскольку вы используете JSF 1.2, я бы использовал ваше третье решение:

XHTML:

<body onLoad="doOnLoad();">
    <h:outputFormat id="myString" value="Hello {0}" styleClass="hidden">
        <f:param value="World" />
    </h:outputFormat>

JavaScript:

function doOnLoad() {
    // do something with the String
    alert(document.getElementById('myString').innerHTML);
}

CSS:

.hidden {
    display:none;
}

использованная литература

person LaurentG    schedule 12.02.2014

JSF в контексте этого вопроса является просто генератором кода HTML/JS. На самом деле вы ничего не передаёте из JSF в HTML/JS. На самом деле вы просто позволяете JSF на веб-сервере печатать желаемый код HTML/JS, чтобы веб-браузер, в свою очередь, мог правильно его выполнить.

Итак, все, что вам нужно сделать, это просто написать код JSF таким образом, чтобы он печатал именно тот код JS, который вам нужен.

<script>
    var text = '<h:outputFormat value="Hello {0}"><f:param value="World" /></h:outputFormat>';
</script>

При открытии страницы JSF в браузере (другими словами, при отправке HTTP-запроса на сервер, который вызывает FacesServlet, который, в свою очередь, выполняет всю работу JSF по созданию HTML/JS), а также при щелчке правой кнопкой мыши и Просмотр исходного кода вы должны увидеть что-то вроде этого:

<script>
    var text = 'Hello World';
</script>

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

Однако будьте осторожны со специальными символами, такими как символы новой строки. Вам может потребоваться создать пользовательскую функцию EL, которая делегирует Apache Commons Lang StringEscapeUtils#escapeJavaScript(), см. также Как избежать JavaScript в JSP?


Обновление: судя по комментариям, вы используете JSF 1.1. Если обновление невозможно (однако я настоятельно рекомендую это сделать; практически любой проект JSF 1.1 без изменений кода совместим с JSF 1.2), тогда вам нужно поместить разметку, отличную от JSF, в <f:verbatim> «обычным способом».

<f:verbatim><script>
    var text = '</f:verbatim><h:outputFormat value="Hello {0}"><f:param value="World" /></h:outputFormat><f:verbatim>';
</script></f:verbatim>

См. также среди прочего /">Почему Facelets предпочтительнее JSP в качестве языка определения представления, начиная с JSF2.0? и JSF/Facelets: почему не рекомендуется смешивать JSF/Facelets с тегами HTML? для некоторой справочной информации.

Согласно вашей жалобе,

Дополнительным недостатком является то, что я не могу поместить это в <head>, так как оно должно быть внутри <f:view>.

это абсолютно не так. Определенно вы можете поместить это в <head>. Просто переместите <f:view> изнутри <body> наружу <body>, обернув <head> и <body> или даже <html>.

<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<!DOCTYPE html>
<html lang="en">
    <f:view>
        <head>...</head>
        <body>...</body>
    </f:view>
</html>
person BalusC    schedule 12.02.2014
comment
Спасибо за Ваш ответ. На самом деле это был первый подход, который я попробовал, но забыл упомянуть об этом в своем вопросе здесь. Моя проблема с ним в том, что он просто не работает для меня. Куда бы я ни помещал ваш фрагмент кода, исходный код HTML показывает: var text = ''; (я пробовал в ‹head› и в ‹body› внутри ‹f:view›). Я новичок в JSF и изучаю существующий сложный проект, поэтому пока не могу сказать, требуется ли дальнейшая настройка. - person SebastianH; 12.02.2014
comment
Работает на меня. Ваша проблема вызвана чем-то другим, не видимым в представленной информации. Трудно ответить, пока вы не уточните, это не будет работать с точки зрения разработчика, а не с точки зрения конечного пользователя. - person BalusC; 12.02.2014
comment
Извините, мой комментарий еще не был сделан. Я всегда влюбляюсь в (SHIFT) ENTER в поле для комментариев :( - person SebastianH; 12.02.2014
comment
Какую реализацию/версию JSF вы используете? Вы использовали тестовый код точно так же, как в моем ответе, или вы заменили value свойством компонента или переменной пакета? - person BalusC; 12.02.2014
comment
Я обнаружил, что Apache MyFaces 1.1.4 используется. Боюсь, это подразумевает, что на самом деле используется JSF 1.1? Возможно, мне придется обновить вопрос. Я скопировал ваш код как есть и не изменил EL, поэтому ссылка на какой-либо компонент не используется. - person SebastianH; 12.02.2014
comment
Да, это реализация JSF 1.1. Однако теоретически код должен работать так же хорошо для JSF 1.1. Вам нужно только поместить <f:verbatim> вокруг разметки, отличной от JSF, обычным способом (или, лучше, обновиться до JSF 1.2, чтобы вам больше не нужен беспорядок <f:verbatim>; проекты JSF 1.1, как правило, без каких-либо необходимых изменений кода совместимы с JSF 1.2). ). - person BalusC; 12.02.2014