Как получить значение ui: param в поддерживающем компоненте

Я передаю параметр p1 на другую страницу page.xhtml:

<ui:include src="page.xhtml">
    <ui:param name="p1" value="#{someObject}"/>
</ui:include>

Возможно ли оценить #{p1} внутри метода @PostConstruct компонента поддержки page.xhtml? Используя следующий фрагмент кода, #{p1} не может решить:

FacesContext currentInstance = FacesContext.getCurrentInstance();
currentInstance.getApplication().evaluateExpressionGet(currentInstance, "#{p1}", String.class);

Зачем мне это нужно?

Я использую файл xhtml (скажем, component.xhtml) в качестве настраиваемого компонента пользовательского интерфейса. В этом файле есть компонент поддержки, из которого я должен получить данные о компонентах. Поскольку я включаю этот файл xhtml дважды или более в свою основную страницу JSF, я хочу передать разные объекты каждому из component.xhtml, чтобы мой компонент каждый раз работал с моими пользовательскими данными.


person Mohsen    schedule 22.01.2013    source источник
comment
В каком методе поддержки bean-компонента находится этот код?   -  person partlov    schedule 22.01.2013
comment
обновил мой вопрос: метод @PostConstruct.   -  person Mohsen    schedule 22.01.2013
comment
Это может быть проблемой. Метод @PostConstruct может быть выполнен до создания страницы. Попробуйте определить f:event для preRenderView и посмотрите, разрешится ли это.   -  person partlov    schedule 22.01.2013
comment
Звучит странно! preRenderView / preRenderComponent listener не вызывается на включенной странице.   -  person Mohsen    schedule 22.01.2013
comment
Кажется, что preRenderView не работает на включенной странице. Смотрите: stackoverflow.com/questions/12543405/   -  person Mohsen    schedule 22.01.2013
comment
Вы используете Mojarra или MyFaces? Эта конструкция определенно не работает в MyFaces. В Mojarra есть способ, но вы бы предпочли не зависеть от специфического поведения JSF. Если вы разработаете конкретное функциональное требование, мы сможем предложить правильное решение.   -  person BalusC    schedule 22.01.2013
comment
Я использую Mojarra, и меня не волнует, имею ли я прямую зависимость от Mojarra, поскольку я не буду переключаться на MyFaces.   -  person Mohsen    schedule 22.01.2013
comment
Добавлено Зачем мне это нужно?   -  person Mohsen    schedule 22.01.2013


Ответы (3)


В Mojarra вы можете получить его как атрибут FaceletContext. Вы можете получить его в @PostConstruct управляемого bean-компонента, на который гарантированно будет ссылка / построена в первый раз на включенной странице (и, следовательно, не на родительской странице до <ui:param> объявлен в компоненте дерево).

FaceletContext faceletContext = (FaceletContext) FacesContext.getCurrentInstance().getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
Object p1 = faceletContext.getAttribute("p1");

В MyFaces весь FaceletContext недоступен в управляемых bean-компонентах, так как он отбрасывается к концу времени сборки представления, и тогда эта конструкция не будет работать. Чтобы не зависеть от реализации JSF, вы можете подумать о том, чтобы вместо этого установить его через <c:set scope="request">. Затем он доступен как атрибут запроса.

Что касается конкретных функциональных требований, рассмотрите возможность создания составного компонента с компонентом поддержки. Для некоторых примеров см. нашу вики-страницу о составных компонентах и этот блог о с использованием нескольких компонентов ввода в составном компоненте. См. Также Когда следует использовать ‹ui: include›, файлы тегов, составные компоненты и / или пользовательские компоненты?

person BalusC    schedule 22.01.2013
comment
управляемый bean-компонент, на который гарантированно будет ссылка / построена в первый раз на включенной странице. Если страница загружается одновременно с родительской страницей, она все равно должна быть в порядке, если она никогда не использовалась в родительском праве? Или нам нужно лениво загрузить его, чтобы убедиться в этом? - person Kenny Steegmans; 03.12.2020
comment
Если не можете гарантировать, просто разделитесь на новый bean-компонент. При необходимости вы можете легко внедрить родительский компонент. - person BalusC; 03.12.2020
comment
Ну, у меня есть bean-компонент специально для моего композита, но мой параметр не добавляется в контекст, даже когда я лениво загружаю композит (с использованием наложения простых шрифтов). - person Kenny Steegmans; 03.12.2020
comment
Композитный? Это не включенная страница. Вместо этого используйте вспомогательный компонент. См. Также ссылки внизу ответа. Затем вы можете просто сделать что-то вроде stackoverflow.com/q/21525669 - person BalusC; 03.12.2020
comment
Извините, я имел в виду композицию, а не композицию. (Не уверен в разнице, так как я никогда не использовал композит) - person Kenny Steegmans; 03.12.2020

Параметр недоступен в методе @PostConstruct; вы можете использовать событие preRenderComponent для инициализации параметров внутри вашего вспомогательного bean-компонента; просто поместите его после состава ui: включенной страницы, он будет выполнен до рендеринга самой включенной страницы.

Следуя примеру OP передачи параметра p1 в шаблон page.xhtml

главная страница:

<ui:include src="page.xhtml">
    <ui:param name="p1" value="#{someObject}"/>
</ui:include>

page.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    ...>

<ui:composition>
    <f:event listener="#{backingBean.init(p1)}" type="preRenderComponent"/>
        ...

</ui:composition>

</html>

BackingBean.java:

@ViewScoped
 public class BackingBean{

     private Object p1;
     public void init(Object value){        
     this.p1=p1;
    }

    ...
 }

событие запускается перед рендерингом тега ui: Composition, то есть перед рендерингом page.xhtml

person Bruno F    schedule 17.10.2018

Это работает для меня:

<ui:include src="page.xhtml">
     <ui:param name="p1" value="#{someObject}"/>
</ui:include>

page.xhtml:

<c:set var="data" value="#{p1}" scope="request"/>

Ваш bean:

@ViewScoped
public class ManagedBean{

     private Object someObject;

     public Object getSomeObject(){
         if(someObject== null){
            HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
            someObject= request.getAttribute("data");
          }
          return someObject;
     }

     public void setSomeObject(Object someObject){
          this.someObject = someObject;
     }}
person ravenskater    schedule 03.05.2017