【问题标题】:How to access EntityManager in the Backing Component of a composite component?如何在复合组件的 Backing Component 中访问 EntityManager?
【发布时间】:2016-09-29 03:22:57
【问题描述】:

我用一个支持组件制作了一个复合组件:

复合组件的Xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:composite="http://java.sun.com/jsf/composite" xmlns:c="http://java.sun.com/jsp/jstl/core">

    <composite:interface componentType="editorCompositeComponent">
        <!-- ...bunch of attributes... -->
        <composite:attribute name="content" type="java.lang.String" default="" />
    </composite:interface>

    <composite:implementation>
        <!-- ... other components ... -->
        <p:editor widgetVar="editorWidget" value="#{cc.attrs.content}" width="600" maxlength="8000" />
        <p:commandButton action="#{cc.save(cc.attrs.caseId)}" value="Save" />
    </composite:implementation>

</html>

支持组件:

@FacesComponent("editorCompositeComponent")
public class EditorCompositeComponent extends UINamingContainer {

    private String content;
    // bunch of other variables

    public void save(String caseId) {

    MemoFile memoFile = new MemoFile();
    memoFile.setContent(content);
    memoFileService = new MemoFileService();
    // Normally this service would be Injected but Injection
    // isn't possible in @FacesComponent

    memoFileService.save(memoFile);
    // the save-method just calls EntityManager's merge etc.
    // It works well in all the ManagedBeans
    }
    // all the getters and setters
}

所以,无法注入东西,因此无法找到 EntityManager,那么如何将编辑器的内容保存在复合组件中呢?

【问题讨论】:

    标签: jsf primefaces composite-component


    【解决方案1】:

    UI 组件不支持依赖注入。这有点过于紧密的职责耦合。 UI 组件实例不应该由容器管理。

    最好的办法是为任务创建一个单独的请求范围的托管 bean。

    @Named
    @RequestScoped
    public class EditorCompositeBean {
        // ...
    }
    

    您可以将复合组件实例传递给它的操作方法:

    <p:commandButton ... action="#{editorCompositeBean.save(cc)}" />
    

    或者使用那个 bean 作为模型来代替:

    <composite:interface componentType="editorCompositeComponent">
        <composite:attribute name="value" type="com.example.EditorCompositeBean" />
    </composite:interface>
    
    <composite:implementation>
        <p:editor ... value="#{cc.attrs.value.content}" />
        <p:commandButton ... action="#{cc.attrs.value.save}" />
    </composite:implementation>
    

    【讨论】:

    • 谢谢。实际上,我首先使用 ManagedBean 作为组件的支持 bean,但意识到因为我想在同一个视图中拥有同一个复合组件的多个实例,所以我必须为它创建一个 @FacesComponent。
    猜你喜欢
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2012-03-10
    • 2016-10-12
    相关资源
    最近更新 更多