繁体   English   中英

得到 <h:outputText> 作为支持bean的ManagedProperty

[英]get <h:outputText> as ManagedProperty in backing bean

首先,我想说我是JSF的新手。

我想创建一个简单的复合组件,可用于编辑文章。 它应该以这种方式工作:

  1. 复合组件看起来像这样<my:article article="#{interestedBean.article}" />
  2. ArticleBean负责处理复合组件的数据(这里是save方法)
  3. 想要使用文章的每个页面都需要将复合组件添加到视图,将Article对象添加到辅助bean
  4. Article对象将传递给复合组件,其值将在ArticleBean更改

问题是我不知道如何通过视图将实体( Article对象)从一个bean(感兴趣的bean)传递到另一个( ArticleBean )。

示例(伪代码;让我们假设Article实体是简单的String对象,因此我们不需要使用转换器):

// input bean
public class HomePageBean {
    private Article article;
    @PostConstruct
    public void init() {
        this.article = new Article();
        this.article.setText("welcome on home page");
    }
    public void setArticle(Article article) {
        this.article = article;
    }
    public Article article() {
        return article; // on real page article will be taken from database
    }
}

// view
<h:form>
    <h:outputText value="#{articleBean.article.text}">
        <f:attribute name="value" value="#{homePageBean.article.text}" />
    </h:outputText>
</h:form>

// output bean
public class ArticleBean {
    private Article article;
    public void setArticle(Article article) {
        this.article = article;
    }
    public Article getArticle() {
        return article;
    }
    public void save() {
         // save article data to database
    }
}

// entity
public class Article {
    private article text;
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
}

问题是未设置SecondBean.entity.text值。 如何从视图中将参数传递给backing bean? 我试图使用@ManagedProperty(value="#{param.article}")设置Article@ManagedProperty(value="#{param.article}")但是<h:outputText>处于表单中,因此值将作为randomformname:article传递。

对不起我的英语不好

实际上这个问题需要澄清。 所以我对你可能想做的事情有两个基本的想法。

在一个视图上简单地共享信息

如果要在同一视图上共享信息,可以使用@ManagedProperty将托管bean互相注入。 请记住,注入的bean的范围不会小于注入的bean。 实际上,如果您需要的只是一个文章对象,那么我没有看到在您的情况下使用两个托管bean的原因,但是,您仍然可以使用

@ManagedBean
@RequestScoped
public class BaseBean {

    private Article article;

    @ManagedProperty(value="#{injectedBean}")
    private InjectedBean injectedBean;

}

要初始化您想要相同的托管bean的两个属性,可以使用带@PostConstruct注释的init方法(但有很多替代方法),就像在这里一样

@PostConstruct
public void init() {
    Article article = new Article("Welcome");
    this.article = article;
    injectedBean.setArticle(article);
}

在视图之间共享信息

在这种情况下,用户在第一个视图上选择他想要编辑的文章, 并将传递给第二个视图。 在这种情况下,用户选择他想要在一个页面上操作的文章( welcome.xhtml ),并且实际操作发生在另一页面上( manipulation.xhtml )。

常见的方法是每个页面都被它自己的bean绑定,所以在上面提到的设置中,'base bean'将失去它的注入。 因此, welcome.xhtml视图将使用从某个地方弹出该页面的一些文章对象,并在按钮点击时将其传递给第二个视图。

bean与文章对象的reagrd相同。

@ManagedBean
@RequestScoped
public class BaseBean {

    private Article article;

}

@ManagedBean
@RequestScoped
public class InjectedBean {

    private Article article;

}

实际传递将在按钮点击期间发生,例如

    <h:form>
        <h:commandButton value="Manipulation" action="manipulation.xhtml">
            <f:setPropertyActionListener target="#{injectedBean.article}" value="#{baseBean.article}"/>
        </h:commandButton>
    </h:form>

在代码中,属性动作侦听器方法是为第二个视图实例化一个bean,并使用基本bean的属性设置它的属性。

使用get参数进行页面加载

有时它更多的是不包括命令按钮来触发导航到下一个视图,但提供了编辑页面的简单链接。 它可以通过使用<f:param>标签来实现。 在JSF中有两种处理参数的基本方法:使用页面操作/ preRenderView事件或使用@ManagedProperty直接在托管bean中注入它们。

  1. 使用Page actions / preRenderView事件

作业将由目标视图完成

<f:metadata>
    <f:viewParam id="articleId" name="articleId" value="#{injectedBean.id}" />
    <f:event type="preRenderView" listener="#{injectedBean.initEvent}" />
</f:metadata>

对于preRenderView事件和

<f:metadata>
    <f:viewParam id="articleId" name="articleId" value="#{injectedBean.id}" />
    <f:viewAction action="#{injectedBean.initEvent}" />
</f:metadata>

用于页面操作。 托管bean( InjectedBean对象)将具有以下init方法

public void initEvent() {
    if (id == null) {
        String message = "No id specified in request";
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
        return;
    }
    //use your service method to load the article
    //article = articleService.findById(id);
    //and add messages appropriately
}
  1. 使用@ManagedProperty注释

该作业将通过以下bean方法完成,该方法使用@PostConstruct注释,并且参数依赖注入。 请记住, @RequestScoped设置正常工作,bean必须是@RequestScoped ,但是有其他bean范围的解决方法。

@ManagedProperty(value="#{param.articleId}")
private Integer id;

@PostConstruct
public void initPostConstruct() {
    if (id == null) {
        String message = "No id specified in request";
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(message));
        return;
    }
    //use your service method to load the article
    //article = articleService.findById(id);
    //and add messages appropriately
}

在下一个视图( manipulation.xhtml )中初始化bean的任何方式。 由BalusC提供的这两种方式的非常有用的比较可以在这里找到。

例如,可以通过简单的<h:link>处理对该视图的导航,例如

<h:link value="Manipulate" outcome="manipulation.xhtml" >
    <f:param name="articleId" value="#{baseBean.article.id}" />
</h:link>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM