2013-03-21 4 views
1

Прогуливаясь дальше по пути понимания области просмотра jsf 2, я снова сталкиваюсь с проблемами.ViewScope: Задайте экземпляр объекта «правый» составной компонент

Существует несколько экземпляров связанного объекта моего составного компонента, и значение параметра не похоже на «правильное».

Я имею ту же начальную установку как в Auto-instantiate session-scoped bean from view-scoped bean

Теперь я создал составной компонент:

<composite:interface componentType="helloWidget"> 

</composite:interface> 

<composite:implementation> 
    <h:outputText value="Visible state of this composite component: #{cc.visibleState}"/> 
</composite:implementation> 

и его Java аналог

@FacesComponent(value = "helloWidget") 
public class HelloWidget extends UINamingContainer implements Serializable { 

    private static final long serialVersionUID = 2L; 
    private boolean visible; 

    public void show() { 
     System.out.println("Setting visible state to true " + this); 
     visible = true; 
    } 

    public void hide() { 
     System.out.println("Setting visible state to false " + this); 
     visible = false; 
    } 

    public String getVisibleState() { 
     System.out.println("Getting visible state of " + this + "(" + visible + ")"); 
     return String.valueOf(visible); 
    } 
} 

Я тогда модернизированный мой ViewBean.java

private HelloWidget helloWidget; 
private boolean visible; 

public String getVisibleState() { 
    return String.valueOf(visible); 
} 

public void actionShow(ActionEvent ae) { 

    visible = true; 
    helloWidget.show(); 
} 

public void actionHide(ActionEvent ae) { 

    visible = false; 
    helloWidget.hide(); 
} 

public HelloWidget getHelloWidget() { 
    return helloWidget; 
} 

public void setHelloWidget(HelloWidget helloWidget) { 
    this.helloWidget = helloWidget; 
} 

и мой hello.xhtml:

<f:view> 
    <h:form> 
     <h:outputText value="View-scoped bean visible value: #{viewBean.visibleState}"/> 
     <br/> 
     <mycc:helloWidget binding="#{viewBean.helloWidget}"/> 
     <br/> 
     <h:commandButton value="Show" actionListener="#{viewBean.actionShow}"/> 
     <h:commandButton value="Hide" actionListener="#{viewBean.actionHide}"/> 
    </h:form> 
</f:view> 

Когда я теперь ударил кнопки показать/скрыть, значение свойства «видимых» в окне изменения области видимости боба, как ожидалось. «Видимое» значение свойства HelloWidget также изменяется, но когда страница отображается, отображается другой экземпляр HelloWidget, который имеет видимый набор (по умолчанию) false.

Что я здесь делаю неправильно? Есть ли проблема с тем, как я связываю составной компонент?

ответ

1

Компоненты создаются при создании/восстановлении вида. Таким образом, они, таким образом, запрашивают область действия. Любое состояние, которое вы хотите сохранить в области представления, должно храниться в состоянии представления JSF. Обычный подход заключается в том, чтобы позволить геттерам/сеттерам свойств, представляющих делегат состояния области зрения, в UIComponent#getStateHelper().

Таким образом, это должно сделать:

@FacesComponent(value = "helloWidget") 
public class HelloWidget extends UINamingContainer implements Serializable { 

    private static final long serialVersionUID = 2L; 

    public void show() { 
     setVisible(true); 
    } 

    public void hide() { 
     setVisible(false); 
    } 

    public Boolean getVisible() { 
     return (Boolean) getStateHelper().eval("visible"); 
    } 

    public void setVisible(Boolean visible) { 
     getStateHelper().put("visible", visible); 
    } 
} 

Вы однако другой потенциальная проблема не связана с этим вопросом: использование binding на представлении области видимости свойство компонента вызывает вид области видимости компонент сам по себе быть воссозданы при каждом запросе , С особой тщательностью используйте атрибут binding. Эта проблема имеет те же основания, что и в разделе JSTL in JSF2 Facelets... makes sense?.

+0

Благодарим за оказанную (как обычно) неоценимую помощь. Я попробовал это, но получил возвращаемое значение null для моего getVisible(), что, безусловно, связано с проблемой, описанной в вашем связанном ответе. Даже установка частичного сохранения состояния в значение false не разрешает это. Так что, в принципе, если я хочу «контролировать» мои пользовательские компоненты из компонента так, как я, я должен вернуться к области сеанса? – Tom

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