如何在 JSF 视图中使用抽象 class 作为 CDI 托管 bean

How to use abstract class as CDI managed bean in JSF view

我可以在 JSF 视图中使用抽象 class 作为 CDI 托管 bean 吗?我想在派生 class 中设置或覆盖属性,并在父抽象 class 的 JSF 页面中使用它。派生视图设置上下文,模板父视图必须显示为所有子视图的公共部分。 我听说我可以在 JSF 视图中使用带有 @Named 注释的抽象 class,但是我得到错误

Target Unreachable, identifier 'viewModel' resolved to null

如果我将摘要 class 更改为典型的 class 那么它的工作。可能无法在 JSF 视图中使用抽象 class?

ViewModel.java

@Named
@ConversationScoped
@Inherited
@Documented
@Stereotype
@Target({ TYPE })
@Retention(RUNTIME)
public abstract class ViewModel {
    private String foo;

    public void setFoo(String foo) {
        this.foo = foo;
    }

    public String getFoo() {
        return foo;
    }

    abstract void bar();
}

派生ViewModel.java

@Named
@ConversationScoped
@Inherited
@Documented
@Stereotype
@Target({ TYPE })
@Retention(RUNTIME)
public class DerivedViewModel extends ViewModel {
    public void init() {
        this.setFoo("Foo");
    }

    @Override
    void bar() {;}
}

View.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:p="http://primefaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions"
    xmlns:sys="http://argustelecom.ru/system" xmlns:o="http://omnifaces.org/ui">

    <ui:param name="viewModel" value="#{viewModel}" />

    <ui:define name="body">
        <h:outputText value="#{viewModel.foo}" />

        <ui:insert name="derived" />
    </ui:define>

</ui:composition>

派生View.xhtml

<ui:composition template="View.xhtml" xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:p="http://primefaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions"
    xmlns:sys="http://argustelecom.ru/system" xmlns:o="http://omnifaces.org/ui">

    <ui:param name="viewModel" value="#{derivedViewModel}" />
    <ui:define name="metadata">
        <f:metadata>
            <f:viewAction action="#{derivedViewModel.init()}"/>
        </f:metadata>
    </ui:define>

    <ui:define name="derived">
        blablabla
    </ui:define>

</ui:composition>

忘记 EL 或 JSF。从 OO 的角度思考。你能打这个电话吗?

viewModel.foo

答案是否定的,因为abstractviewModel不能作为abstractclassViewModel的实例存在。出于完全相同的原因,您不能在 EL 中使用它。