Просмотр параметров в разных бобах - PullRequest
2 голосов
/ 25 августа 2011

У меня есть страница с именем trip.xhtml, где я беру параметры из URL, используя следующий код:

<f:metadata>
    <f:viewParam name="tripid" value="#{tripBean.tripId}" />
    <f:viewParam name="seats" value="#{tripBean.seats}" />
    <f:event type="preRenderView" listener="#{tripBean.processParams}" />
</f:metadata>

TripBean выглядит следующим образом (упрощенно):

@ManagedBean
@RequestScoped
public class TripBean implements Serializable {

    private static final long serialVersionUID = -4885781058258859229L;

    private Long tripId;
    private int seats;

    // Getters and setters for tripId and seats

В нижней части страницы trip.xhtml у меня есть h:link:

<h:link outcome="/customer/booking.xhtml" value="Book this trip"
    includeViewParams="true" />

Я ожидаю, что URL, который я получу, когда я нажму на эту ссылку, будет похож на "/customer/booking.jsf?tripid=2&seats=1",Это только тот случай, когда я помещаю следующий код на мою booking.xhtml страницу:

<f:metadata>
    <f:viewParam name="tripid" value="#{tripBean.tripId}" />
    <f:viewParam name="seats" value="#{tripBean.seats}" />
</f:metadata>

Хотя на самом деле я хочу использовать другой компонент.Изменяя код на:

<f:metadata>
    <f:viewParam name="tripid" value="#{bookingBean.tripId}" />
    <f:viewParam name="seats" value="#{bookingBean.seats}" />
</f:metadata>

BookingBean также имеет 2 свойства tripId и seats, которые идентичны TripBean, но когда я пытаюсь щелкнуть ссылку сейчас, я толькосм. параметр seat, который установлен в 0. ("/customer/booking.jsf?seats=0")

Кто-нибудь имеет какие-либо идеи, почему я не могу передать параметры просмотра на другую страницу, когда я пытаюсь использовать другой компонент?хранить их в?И если невозможно сохранить его в другом компоненте, как я могу поместить эти значения из TripBean в BookingBean?

Быстрый обходной путь, который я использовал: Не используя includeViewParams="true", но добавляя параметры вссылка вручную (см. ниже) «исправляет» проблему.Хотя мне все еще интересно, почему это не будет работать с includeViewParams!

<h:link outcome="/customer/booking.xhtml" value="#{msg['page.trip.booking']}">
    <f:param name="tripid" value="#{tripBean.tripId}" />
    <f:param name="seats" value="#{tripBean.seats}" />
</h:link>

Ответы [ 2 ]

2 голосов
/ 25 августа 2011

f:viewParam работает точно так же, как h:inputText.Это означает, что оно использует то же выражение, что и источник (при рендеринге) и как цель (при обновлении модели).Если бы у вас было:

<h:inputText value="#{a.test}" />

Вы бы никогда не спросили «как заставить inputText читать из b.foo и писать в a.test», хотя все, похоже, ожидают такого поведения от f:viewParam.

В любом случае, есть простой ответ.Чтобы добавить любые значения в ссылку, вам просто нужно использовать f:param:

<h:link outcome="/customer/booking.xhtml" value="Book this trip" >
    <f:param name="tripid" value="#{bookingBean.tripId}" />
    <f:param name="seats" value="#{bookingBean.seats}" />
</h:link>
1 голос
/ 25 августа 2011

Содержимое ссылки, соответствующее следующему тегу:

<h:link outcome="/customer/booking.xhtml" value="Book this trip"
            includeViewParams="true" />

генерируется во время фазы ответа на запрос для представления trip.xhtml. Если вам нужно, чтобы URL-адрес содержал значения параметров представления, вы должны указать эти значения в URL-адресе, используемом для доступа к представлению, или установить эти значения в модели до завершения фазы рендеринга-ответа. Если вы не выполните ни одно из этих действий, сгенерированная гиперссылка будет содержать значения по умолчанию для параметров просмотра.

Проще говоря, вы должны:

  • либо обеспечивает доступ к представлению trip.xhtml с необходимыми параметрами: trip.xhtml?tripid=x&seats=y, особенно если к представлению необходимо обращаться с параметрами в любое время.
  • или вы должны установить значения в методе, который выполняется до того, как ссылка будет отображена средой выполнения JSF. Конструктор класса BookingBean или аннотированный метод @PostConstruct в классе будут идеальными местами для установки значений. Вы также можете сбросить / обновить значения компонента в других методах вашего управляемого компонента в случае действий, выполняемых в представлении. Обратите внимание, что среда выполнения JSF будет вызывать getTripId и getSeats для включения значений параметров представления tripId и seats в результирующий URL-адрес, поэтому вам следует также проверить поведение этих методов.

Ваш вопрос о том, почему вы не можете указать bookingBean в выражении EL для booking.xhtml, вместо этого требуя указать предположительно неожиданное значение tripBean, связан с тем, что атрибут includeViewParams Тег link будет содержать параметры to-view, а не from-view. Проще говоря, среда выполнения JSF будет вызывать bookingBean.getTripId() и bookingBean.getSeats(), а не tripBean.getTripId() и tripBean.getSeats().

Хотя это может показаться нелогичным, вы должны понимать, что спецификация JSF трактует этот сценарий совершенно по-другому. В большинстве взаимодействий, выполняемых пользователем, URL-адрес действия компонента генерируется, когда пользователь выполняет действие, а не до тех пор. Тег link, с другой стороны, требует преимущественного вычисления URL, и, следовательно, среда выполнения JSF трактует это совсем по-другому, как «преимущественную навигацию». При создании URL-адреса объекты, относящиеся к параметрам представления целевого представления, должны быть доступны, чтобы URL-адрес имел смысл. Причина, по которой значения равны 0 в URL, заключается в том, что во время этой оценки создается новый экземпляр BookingBean, и вместо него используются значения по умолчанию. Совершенно очевидно, что вы можете избежать этого, используя вместо этого TripBean (и большинство примеров includeViewParams демонстрируют это), или вы можете установить значения во время создания объекта BookingBean.

...