2011-02-04 2 views
4

Я видел другие вопросы о вызове bean-конструктора и ViewScope, и у меня все еще есть трудности. Проблема, которую я вижу, включает в себя две конкретные страницы в моем приложении. Первый - это dataTable (на данный момент он заполнен случайно генерируемыми данными, но в конечном итоге вызывает базу данных), вторая страница представляет собой довольно простую страницу отображения, на которой информация из выбранной строки отображается в форме для редактирования или просмотра - это моя страница detail.xhtml. Это проблема для этой страницы; его конструктор вызывается дважды: сначала, когда я перехожу к странице, снова, когда я нажимаю commandButton, отправлять ли изменения или отменять изменения, не имеет значения, конструктор bean bean detail.xhtml вызывается во второй раз.Конструктор ViewScope дважды называется, не уверен, почему

Мой фасоль: @ViewScoped, импорт javax.faces.bean.ViewScoped. Несколько других деталей, которые могут иметь значение, но если они это делают, я не понимаю, почему: мой UserDetailBean.java наследуется от базового компонента (который я так первоначально называл UIBaseBean.java). Теперь мой UIBaseBean - @RequestScoped. Насколько я понимаю, это не должно меняться, потому что мой UserDetailBean - @ViewScoped, пожалуйста, исправьте меня, если я ошибаюсь.

Другая деталь, которая может изменить ситуацию, - это настройка переменной в конструкторе как UIBaseBean, так и UserDetailBean. Я хочу показать местоположение пользователя на панели инструментов в верхней части моих страниц. Для этого я создал переменную в UIBaseBean:

protected String toolbarDescription; 

Я также представил и присваивателя в UIBaseBean. В конструкторе UIBaseBean, я определить переменную:

toolbarDescription = "fix me"; 

Это определение просто так что я знаю, чтобы переопределить переменную в вспомогательном компоненте для какой-либо конкретной страницы в моем приложении. В моем UserDetailBean я назначаю новое значение для описания панели инструментов String. Это значение отображается на странице detail.xhtml. В противном случае компонент bean для моей detail.xhtml страницы очень прямолинейный, он получает и устанавливает свойства для отображения данных в форме на странице detail.xhtml.

Детальная страница настроена таким образом, чтобы навигация к ней происходила с перенаправлением, а отключение (при нажатии кнопки commandButton) происходит с перенаправлением. Я пробовал использовать навигационные правила faces-config с переадресацией и без нее, а также скрытую навигацию с переадресацией и без нее, но конструктор UserDetailBean всегда вызывается дважды.

О, я установил точку останова в переменной панели инструментов в моем конструкторе UserDetailBean, который останавливает программу дважды: когда страница сначала вызывается, и снова после того, как я нажимаю кнопку commandButton на странице подробностей.

Из того, что я описал, может ли кто-нибудь сказать мне, почему мой конструктор вызывается дважды? Я неправильно проектировал свой компонент, или проблема глубже в моем приложении?

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 
import javax.faces.event.ActionEvent; 
import [package name].UIBaseBean;  
import java.util.Locale; 
import javax.faces.bean.ManagedProperty; 


@ManagedBean 
@ViewScoped 

public class UserDetailBean extends UIBaseBean { 

@ManagedProperty(value = "#{param.action}") 
private String action; 

private String firstName; 
private String lastName; 
private String jobTitle; 
private String DOH; 
private String location; 
private String status; 
private String comments; 
@ManagedProperty(value = "#{param.id}") 
private String id; 
private String tabTitle; 

private boolean editMode; 
private boolean viewMode; 

private ClUserDetail dBUserDetail;  

    /** Creates a new instance of UserDetailBean */ 
    public UserDetailBean() { 
     toolbarDescription = CoreMsgBundle.getMessageFromResourceBundle("UserDetail", Locale.ENGLISH); 
    } 

ответ

4

Вы должны удалить @RequestScoped и другие связанные с аннотациями из UIBaseBean (и сделать его abstract).

Как только это будет сделано, вам также необходимо зафиксировать @ManagedProperty на #{param} быть либо определенный <f:viewParam> или быть получено ExternalContext#getRequestParameterMap() вместо этого. Невозможно впрыснуть что-то, что имеет меньшую область видимости во что-то, что имеет больший объем (потому что неясно, какой из них следует вводить, поскольку в рамках акцептора может быть больше их). JSF выбрасывает исключение из этого во время строительства bean.

+0

Большое спасибо, это работает точно так же, как я надеялся, что исходный код будет работать. Что касается @ManagedProperty - это пример небольшой информации, без хорошего понимания, что это плохо. Я прочитал [этот ответ] (http://stackoverflow.com/questions/4888942/viewparam-vs-managedpropertyvalue-param-id) и подумал: «О, какая хорошая идея, я сделаю это в своем приложении». – Sean

+0

Ты прав. Я обновил ответ. – BalusC

+0

@balusc У меня есть аналогичная проблема в том, что мой конструктор beans Viewscoped вызывается несколько раз. Компонент расширяет базовый класс, который предоставляет функцию полезности, но не является компонентом. Базовый класс отмечен абстрактом для вашего ответа здесь, но конструктор все еще вызывается дважды. Есть ли другие причины, которые могут произойти? Возможно, стоит отметить, что я объявлял свои бобы в faces-config.xml вместо аннотаций, так как я нахожусь в процессе перехода с 1.2 на 2.0. – Lucas

Смежные вопросы