ViewScope:以“正确"为目标复合组件的对象实例 [英] ViewScope: Target the "right" composite component's object instance

查看:87
本文介绍了ViewScope:以“正确"为目标复合组件的对象实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在进一步了解jsf 2视图范围的过程中,我再次遇到了问题.

Walking further down the understanding process of the jsf 2 view scope, I am running into problems again.

创建了我的复合组件绑定对象的多个实例,并且设置值似乎并不针对正确的"对象.

There are multiple instances of my composite component's bound object created and setting values does not seem to target the "right" one.

我的初始设置与中的自动设置相同会话范围的bean来自视图范围的bean

现在,我创建了一个复合组件:

Now I created a composite component:

<composite:interface componentType="helloWidget">

</composite:interface>

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

及其与之对应的Java

and its java counterpart

@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

I then upgraded my 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:

and my 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>

当我现在点击显示/隐藏按钮时,视图作用域bean中"visible"属性的值将按预期更改. HelloWidget属性的"visible"值也会更改,但是在显示页面时,将显示另一个HelloWidget实例,该实例的visible设置为(默认)false.

When I now hit the show / hide buttons, the value of the "visible" property in the view scoped bean changes as expected. The "visible" value of the HelloWidget property changes too, but when the page is displayed, a different HelloWidget instance is displayed, which has visible set to (default) false.

我在这里做错了什么?我绑定复合组件的方式有问题吗?

What am I doing wrong here? Is there a problem with the way I bind the composite component?

推荐答案

在构建/还原视图期间实例化了这些组件.因此,它们本质上是请求范围内的.您想要保留在视图范围中的任何状态都必须存储在JSF视图状态中.通常的方法是让代表视图范围的状态的属性的获取器/设置器委托给

The components are instantiated during building/restoring of the view. They are essentially thus request scoped. Any state which you'd like to keep in the view scope needs to be stored in the JSF view state. The normal approach is to let the getters/setters of the properties representing the view scoped state delegate to the 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);
    }
}

但是,您还有另一个与此问题无关的潜在问题:在视图作用域的bean属性上使用binding会导致在每个请求期间重新创建视图作用域的bean本身.小心使用binding属性.此问题与 JSF2 Facelets中的JSTL中已说明的理由相同...有意义吗? .

You've however another potential problem not related to this issue: using binding on a view scoped bean property causes the view scoped bean itself to be recreated during every request. Use the binding attribtue with extreme care. This problem has the same grounds as already explained in JSTL in JSF2 Facelets... makes sense?.

这篇关于ViewScope:以“正确"为目标复合组件的对象实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆