根据<composite:interface>
的{{3}}:
嵌套复合组件
实现必须支持复合组件的嵌套。 具体来说,它必须是可能的 复合组件的一部分,用作另一个组件的使用页面 复合材料。当复合组件暴露行为时 使用页面的界面,例如a, , 或其他 行为界面,必须有可能“传播”暴露 在嵌套复合组件的情况下,这样的接口。该 复合组件作者必须确保名称的值 属性在嵌套的所有级别完全匹配以启用此功能 接触工作。实施不需要支持 “重新映射”嵌套复合组件中的名称。
它继续显示嵌套<composite:actionSource>
的示例,但是,我一直在测试一个几乎完全相同的示例,但它不起作用。这是我的代码:
内部复合组件:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="actionText"
type="java.lang.String" default="nestedastest action" />
<composite:actionSource name="someaction" />
</composite:interface>
<composite:implementation>
<h:commandLink id="someaction">#{cc.attrs.actionText}</h:commandLink>
</composite:implementation>
</html>
外部复合材料组件:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:test="http://java.sun.com/jsf/composite/components/test">
<composite:interface name="nestedActionTester"
displayName="A test composite component for nested actions">
<composite:attribute name="actionText"
type="java.lang.String" default="astest action" />
<composite:actionSource name="someaction" />
</composite:interface>
<composite:implementation>
<test:nestedastest actionText="#{cc.attrs.actionText}" />
</composite:implementation>
</html>
的facelet:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:test="http://java.sun.com/jsf/composite/components/test">
<h:head />
<h:body>
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:form id="communityMembersForm">
<div>
<test:astest>
<f:actionListener for="someaction"
binding="#{testController.someActionActionListener}" />
</test:astest>
</div>
<div>
<test:nestedastest>
<f:actionListener for="someaction"
binding="#{testController.someActionActionListener}" />
</test:nestedastest>
</div>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
托管Bean:
package test.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ManagedBean
@ViewScoped
public class TestController {
private static Logger logger =
LoggerFactory.getLogger( TestController.class );
public ActionListener getSomeActionActionListener() {
return new ActionListener() {
@Override
public void processAction( ActionEvent event )
throws AbortProcessingException {
logger.debug( "someaction occurred..." );
}
};
}
}
我正在使用Mojarra 2.1.13:
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.13</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.13</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
在tomcat 6.0.32上:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>el-api</artifactId>
<version>6.0.32</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>servlet-api</artifactId>
<version>6.0.32</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
当我运行此应用程序时,nestedastest action
的链接(直接使用内部复合组件的链接)会导致操作侦听器运行并打印日志消息。但是,当单击astest action
(外部复合组件)时,没有任何反应。鉴于这几乎就是官方JSF javadoc中显示的示例,我希望这可行。知道为什么不是吗?
----------编辑---------
我发现如果我这样修改外部复合组件:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:test="http://java.sun.com/jsf/composite/components/test">
<composite:interface name="nestedActionTester"
displayName="A test composite component for nested actions">
<composite:attribute name="actionText"
type="java.lang.String" default="astest action" />
<composite:actionSource name="someaction" targets="inner" />
</composite:interface>
<composite:implementation>
<test:nestedastest id="inner" actionText="#{cc.attrs.actionText}" />
</composite:implementation>
</html>
请注意,我为actionSource添加了一个targets属性,并为嵌套的复合组件添加了匹配的id
现在它将适当地链接行动。这确实有意义,但文档会让您相信这是不必要的。这是文档中的错误吗?或者在实现中(我在Mojarra 2.1.13和MyFaces 2.1.10上都试过了)?或者在我的理解中?
答案 0 :(得分:0)
该算法默认尝试查找与每个嵌套级别中cc:actionSource名称定义的id相同的组件。在这种情况下,组件id仅在内层定义。如果您不想为每个组件一直使用相同的id,可以使用“targets”属性来指示组件正在讨论的算法,并通过所有级别传递actionListener。