JSF 复合组件:Facet 内容不通过嵌套组件呈现

问题描述 投票:0回答:1

我面临着渲染通过嵌套复合组件中的构面传递的内容的问题。尽管构面被识别为非空,但这些构面内的内容不会出现在最终页面上。以下是我实现的相关部分:

  1. draft_scenario_details.xhtml
<ui:composition template="/virets/templates/base_template.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://xmlns.jcp.org/jsf/core"
                xmlns:p="http://primefaces.org/ui"
                xmlns:virets="http://java.sun.com/jsf/composite/composite">
    <ui:define name="content">
        <virets:scenarioDetails>
            <f:facet name="additionalButtons">
                <p:outputLabel value="MY DRAFT"/>
            </f:facet>
        </virets:scenarioDetails>
    </ui:define>
</ui:composition>
  1. scenarioDetails.xhtml
<ui:composition
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:cc="http://java.sun.com/jsf/composite"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:p="http://primefaces.org/ui"
        xmlns:virets="http://java.sun.com/jsf/composite/composite">
    <cc:interface>
        <cc:facet name="additionalButtons"/>
    </cc:interface>
    <cc:implementation>
        <virets:scenarioDetailsData>
            <f:facet name="additionalButtonsFacet">
                <cc:renderFacet name="additionalButtons"/>
            </f:facet>
        </virets:scenarioDetailsData>
    </cc:implementation>
</ui:composition>
  1. scenarioDetailsData.xhtml
<ui:composition
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:cc="http://java.sun.com/jsf/composite"
        xmlns:p="http://primefaces.org/ui">
    <cc:interface>
        <cc:facet name="additionalButtonsFacet"/>
    </cc:interface>
    <cc:implementation>
        <cc:renderFacet name="additionalButtonsFacet"/>
    </cc:implementation>
</ui:composition>

问题:

通过 viretsScenarioDetails 中的“additionalButtons”方面传递的标签“MY DRAFT”应该在 sceneDetailsData 中呈现,但它不会出现在页面上。

我尝试过的:

  • 确保各个组件的构面名称一致。
  • 直接在中间组件中渲染facet以验证其存在。

问题:

如何确保通过嵌套 JSF 复合组件中的构面传递的内容在最终输出中正确呈现?

任何帮助或见解将不胜感激!

jsf primefaces xhtml facet composite-component
1个回答
0
投票

双重渲染一个facet并不是你想要的。第一个“渲染”应该只是侧面的传递。

scenarioDetails.xhtml:

<ui:composition
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:cc="http://java.sun.com/jsf/composite"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:demo="urn:be:e-contract:ejsf:demo">
    <cc:interface componentType="scenarioDetails">
        <cc:facet name="additionalButtons"/>
    </cc:interface>
    <cc:implementation>
        <div id="#{cc.clientId}">
            <demo:scenarioDetailsData binding="#{cc.scenarioDetailsData}"/>
        </div>
    </cc:implementation>
</ui:composition>

ScenarioDetails.java:

package be.e_contract.demo;

import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UINamingContainer;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ComponentSystemEvent;
import javax.faces.event.ComponentSystemEventListener;
import javax.faces.event.ListenerFor;
import javax.faces.event.PostAddToViewEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@FacesComponent(ScenarioDetails.COMPONENT_TYPE)
@ListenerFor(systemEventClass = PostAddToViewEvent.class)
public class ScenarioDetails extends UIComponentBase implements NamingContainer, ComponentSystemEventListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScenarioDetails.class);

    public static final String COMPONENT_TYPE = "scenarioDetails";

    private UIComponent scenarioDetailsData;

    public void setScenarioDetailsData(UIComponent scenarioDetailsData) {
        this.scenarioDetailsData = scenarioDetailsData;
    }

    public UIComponent getScenarioDetailsData() {
        return this.scenarioDetailsData;
    }

    public ScenarioDetails() {
        setRendererType(null);
    }

    @Override
    public String getFamily() {
        return UINamingContainer.COMPONENT_FAMILY;
    }

    @Override
    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
        UIComponent facet = getFacet("additionalButtons");
        this.scenarioDetailsData.getFacets().put("additionalButtonsFacet", facet);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.