jsf标签_多个动态包含一个JSF标签

jsf标签

每个JSF开发人员都知道ui:include和ui:param标签。 您可以包括一个facelet(XHTML文件)并传递一个对象,该对象将在包含的facelet中可用,如下所示:

<ui:include src="/sections/columns.xhtml"><ui:param name="columns" value="#{bean.columns}"/>
</ui:include>

因此,您可以在带有dynamich列的PrimeFaces DataTable中使用它(p:columns)

<p:dataTable value="#{bean.entries}" var="data" rowKey="#{data.id}" ...>...<ui:include src="/sections/columns.xhtml"><ui:param name="data" value="#{data}"/><ui:param name="columns" value="#{bean.columns}"/></ui:include></p:dataTable>

其中包含的facelet可能包含此代码

<ui:composition xmlns="http://www.w3.org/1999/xhtml"xmlns:p="http://primefaces.org/ui"xmlns:ui="http://java.sun.com/jsf/facelets"...><p:columns value="#{columns}" var="column"><f:facet name="header"><h:outputText value="#{msgs[column.header]}"/></f:facet>// place some input / select or complex composite component for multiple data types here.// a simple example for demonstration purpose:<p:inputText value="#{data[column.property]}"/></p:columns>
</ui:composition>

#{bean.columns}是指描述这些列的特殊对象的列表。 我将此类对象命名为ColumnModel。 所以,这是一个
列出<ColumnModel>。 ColumnModel具有例如属性标头和属性。

继续。 现在,如果要添加对排序/过滤的支持,我们可以使用动态路径,这些路径引用包含排序或/和过滤功能的特定facelet文件。 简单地将src属性绑定到bean属性。

<ui:include src="#{bean.columnsIncludeSrc}"><ui:param name="data" value="#{data}"/><ui:param name="columns" value="#{bean.columns}"/>
</ui:include>

豆有类似的东西

private boolean isFilterRight;
private boolean isSortRight// setter / getterpublic String getColumnsIncludeSrc() {if (isFilterRight && isSortRight) {return "/include/columnsTableFilterSort.xhtml";} else if (isFilterRight && !isSortRight) {return "/include/columnsTableFilter.xhtml";} else if (!isFilterRight && isSortRight) {return "/include/columnsTableSort.xhtml";} else {return "/include/columnsTable.xhtml";}
}

根据所设置的布尔权限,包含了不同的方面。 因此,将要包含的文件的决定放在Bean中。 为了更加灵活,我们可以将表封装在一个复合组件中,并将决策逻辑移至组件类。

<cc:interface componentType="xxx.component.DataTable"><cc:attribute name="id" required="false" type="java.lang.String"shortDescription="Unique identifier of the component in a NamingContainer"/><cc:attribute name="entries" required="true"shortDescription="The data which are shown in the datatable. This is a list of object representing one row."/><cc:attribute name="columns" required="true" type="java.util.List"shortDescription="The columns which are shown in the datatable. This is a list of instances of type ColumnModel."/>...
</cc:interface>
<cc:implementation><p:dataTable value="#{cc.attrs.entries}" var="data" rowKey="#{data.id}" ...>...<ui:include src="#{cc.columnsIncludeSrc}"><ui:param name="data" value="#{data}"/><ui:param name="columns" value="#{cc.attrs.columns}"/></ui:include></p:dataTable>
</cc:implementation>

ui:include如何工作? 这是在构建视图时应用的标记处理程序。 在JSF 2中,组件树根据POST请求构建两次,一次在RESTORE_VIEW阶段,一次在RENDER_RESPONSE阶段。 在GET上,它在RENDER_RESPONSE阶段构建一次。 此行为在JSF 2规范中指定,并且在Mojarra和MyFaces中相同。 如果页面作者使用条件包含或条件模板,则必须在RENDER_RESPONSE中构建视图。 因此,您可以确保ui:include的src属性在渲染阶段之前不久就得到了评估。

但是到了重点! 到目前为止,我写的内容只是介绍了扩展ui:include的动机。 最近,我有一项任务要使用带有动态列的ap:dataTable和p:rowEditor。 在PrimeFaces展示柜中就是这样的 。 问题只是–这种编辑功能不支持p:columns。 我的想法是动态地添加p:column标记多次,但是具有不同的上下文参数。 您可以将其想象为ui:include和ui:param在循环中。 在上面的示例中,我们打算遍历List <ColumnModel>。 每次循环迭代都应在所包含的facelet中使ColumnModel类型的实例可用。 因此,我编写了一个自定义标签处理程序以多次包含任何facelet。

package xxx.taghandler;import xxx.util.VariableMapperWrapper;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagAttributeException;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;/*** Tag handler to include a facelet multiple times with different contextes (objects from "value").* The attribute "value" can be either of type java.util.List or array.* If the "value" is null, the tag handler works as a standard ui:include.*/
public class InlcudesTagHandler extends TagHandler {private final TagAttribute src;private final TagAttribute value;private final TagAttribute name;public InlcudesTagHandler(TagConfig config) {super(config);this.src = this.getRequiredAttribute("src");this.value = this.getAttribute("value");this.name = this.getAttribute("name");}@Overridepublic void apply(FaceletContext ctx, UIComponent parent) throws IOException {String path = this.src.getValue(ctx);if ((path == null) || (path.length() == 0)) {return;}// wrap the original mapper - this is important when some objects passed into include via ui:param// because ui:param invokes setVariable(...) on the set variable mappper instanceVariableMapper origVarMapper = ctx.getVariableMapper();ctx.setVariableMapper(new VariableMapperWrapper(origVarMapper));try {this.nextHandler.apply(ctx, null);ValueExpression ve = (this.value != null) ? this.value.getValueExpression(ctx, Object.class) : null;Object objValue = (ve != null) ? ve.getValue(ctx) : null;if (objValue == null) {// include facelet only oncectx.includeFacelet(parent, path);} else {int size = 0;if (objValue instanceof List) {size = ((List) objValue).size();} else if (objValue.getClass().isArray()) {size = ((Object[]) objValue).length;}final ExpressionFactory exprFactory = ctx.getFacesContext().getApplication().getExpressionFactory();final String strName = this.name.getValue(ctx);// generate unique Id as a valid Java identifier and use it as variable for the provided value expressionfinal String uniqueId = "a" + UUID.randomUUID().toString().replaceAll("-", "");ctx.getVariableMapper().setVariable(uniqueId, ve);// include facelet multiple timesStringBuilder sb = new StringBuilder();for (int i = 0; i < size; i++) {if ((strName != null) && (strName.length() != 0)) {// create a new value expression in the array notation and bind it to the variable "name"sb.append("#{");sb.append(uniqueId);sb.append("[");sb.append(i);sb.append("]}");ctx.getVariableMapper().setVariable(strName,exprFactory.createValueExpression(ctx, sb.toString(), Object.class));}// included facelet can access the created above value expressionctx.includeFacelet(parent, path);// reset for next iterationsb.setLength(0);}}} catch (IOException e) {throw new TagAttributeException(this.tag, this.src, "Invalid path : " + path);} finally {// restore original mapperctx.setVariableMapper(origVarMapper);}}
}

最重要的调用是ctx.includeFacelet(parent,path)。 JSF API中的 includeFacelet(...)方法在相对于当前标记的某个路径上包含了facelet标记。 类VariableMapperWrapper用于通过ui:param从名称到值的映射。 对于带有列的示例,在每次调用includeFacelet(...)之前,变量列还将映射到表达式#{columns [0]},#{columns [1]}等。 好吧,不完全是这些表达式,在列的位置应该是一个唯一的名称,该名称再次映射到columns对象(以避免可能的名称冲突)。 映射器类如下所示

package xxx.util;import java.util.HashMap;
import java.util.Map;
import javax.el.ELException;
import javax.el.ValueExpression;
import javax.el.VariableMapper;/*** Utility class for wrapping a VariableMapper. Modifications occur to the internal Map instance.* The resolving occurs first against the internal Map instance and then against the wrapped VariableMapper* if the Map doesn't contain the requested ValueExpression.*/
public class VariableMapperWrapper extends VariableMapper {private final VariableMapper wrapped;private Map<String, ValueExpression> vars;public VariableMapperWrapper(VariableMapper orig) {super();this.wrapped = orig;}@Overridepublic ValueExpression resolveVariable(String variable) {ValueExpression ve = null;try {if (this.vars != null) {// try to resolve against the internal mapve = this.vars.get(variable);}if (ve == null) {// look in the wrapped variable mapperreturn this.wrapped.resolveVariable(variable);}return ve;} catch (Throwable e) {throw new ELException("Could not resolve variable: " + variable, e);}}@Overridepublic ValueExpression setVariable(String variable, ValueExpression expression) {if (this.vars == null) {this.vars = new HashMap<String, ValueExpression>();}return this.vars.put(variable, expression);}
}

在taglib XML文件中注册标签处理程序,您就可以完成。

<tag><tag-name>includes</tag-name><handler-class>xxx.taghandler.InlcudesTagHandler</handler-class><attribute><description><![CDATA[The relative path to a XHTML file to be include one or multiple times.]]></description><name>src</name><required>true</required><type>java.lang.String</type></attribute><attribute><description><![CDATA[Objects which should be available in the included XHTML files. This attribute can be eitherof type java.util.List or array. If it is null, the tag handler works as a standard ui:include.]]></description><name>value</name><required>false</required><type>java.lang.Object</type></attribute><attribute><description><![CDATA[The name of the parameter which points to an object of each iteration over the given value.]]></description><name>name</name><required>false</required><type>java.lang.String</type></attribute>
</tag>

现在我可以在复合组件中使用它了

<p:dataTable value="#{cc.attrs.entries}" var="data" rowKey="#{data.id}" ...>...<custom:includes src="#{cc.columnsIncludeSrc}" value="#{cc.attrs.columns}" name="column"><ui:param name="data" value="#{data}"/></custom:includes> </p:dataTable>

一个典型的facelet文件(和组件树)包含一个非常规则的p:column标记,这意味着我们能够使用DataTable的所有功能!

<ui:composition xmlns="http://www.w3.org/1999/xhtml"xmlns:p="http://primefaces.org/ui"xmlns:ui="http://java.sun.com/jsf/facelets"...><p:column headerText="#{msgs[column.header]}"><p:cellEditor><f:facet name="output"><custom:typedOutput outputType="#{column.outputTypeName}"typedData="#{column.typedData}"value="#{data[column.property]}"timeZone="#{cc.timeZone}"calendarPattern="#{cc.calendarPattern}"       locale="#{cc.locale}"/></f:facet><f:facet name="input"><custom:typedInput inputType="#{column.inputTypeName}"typedData="#{column.typedData}"label="#{column.inputTypeName}"value="#{data[column.property]}"onchange="highlightEditedRow(this)"timeZone="#{cc.timeZone}"calendarPattern="#{cc.calendarPattern}"locale="#{cc.locale}"/></f:facet></p:cellEditor></p:column>
</ui:composition>

注意 :此方法可以应用于其他组件和用例。 InlcudesTagHandler可以正常运行。 例如,我可以想象在没有基础MenuModel的情况下在PrimeFaces中创建动态Menu组件。 当然,仍然需要某个模型类的列表或数组。

参考:在我们的软件开发博客上, JCG合作伙伴 Oleg Varaksin的一个JSF标签包含了多个动态 。

翻译自: https://www.javacodegeeks.com/2013/06/multiple-dynamic-includes-with-one-jsf-tag.html

jsf标签

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/348051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用Java比较文件

我正在为PACKT创建一系列有关Java网络编程的视频教程。 有整节关于Java NIO。 一个示例程序是通过原始套接字连接将文件从客户端复制到服务器。 客户端从磁盘读取文件&#xff0c;服务器将到达的字节保存到磁盘。 因为这是一个演示&#xff0c;所以服务器和客户端在同一台计算机…

java哈希_Java如何采用哈希码实现分类(以员工分配为例)

5.总程序&#xff1a;下面代码是我们获取的所有的程序代码&#xff0c;如下&#xff1a;public static void main(String[] args) {Scanner scannew Scanner(System.in);System.out.println("请输入员工姓名&#xff1a;");String namescan.nextLine();System.out.pr…

java反射的原理_java反射机制的实现原理

java反射机制的实现原理反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java的反射机制。这里你将颠覆原来对java的理解。Java的反射机制的实现要借助于4个类&#xff1a;class&…

java linkedlist 用法_Java LinkedList addLast()用法及代码示例

Java中的java.util.LinkedList.addLast()方法用于在LinkedList的末尾插入特定元素。用法:void addLast(Object element)参数&#xff1a;此函数接受单个参数element &#xff0c;如上面的语法所示。此参数指定的元素将附加在列表的末尾。返回值&#xff1a;此方法不返回任何值。…

spring 长轮询_Spring集成文件轮询和测试

spring 长轮询我最近实施了一个小项目&#xff0c;在该项目中&#xff0c;我们必须轮询文件夹中的新文件&#xff0c;然后在文件内容上触发服务流。 Spring Integration非常适合此要求&#xff0c;因为它带有一个通道适配器 &#xff0c;该适配器可以扫描文件夹中的新文件&…

java扫描指定package注解_java获取包下被指定注解的类

方案一&#xff1a; 采用reflections 框架(此框架依赖com.google.guava)2、项目依赖org.reflectionsreflections0.9.11com.google.guavaguava21.03、实现代码//入参 要扫描的包名Reflections f new Reflections("com.ggband.netty.execute.command");//入参 目标注解…

您将在下一个项目中使用JSF吗?

上周有一篇很棒的stackoverflow博客文章&#xff0c;主题是“ JavaScript框架的残酷生命周期” 。 这篇文章是关于Javascript UI框架&#xff08;angularjs&#xff0c;angular&#xff0c;jquery和react&#xff09;的流行和流行的速度。 这篇文章的关键指标是每月关于框架的问…

java dao层 service层_dao层与service层的区别

service是业务层&#xff0c;dao是数据访问层。这个问题我也曾经考虑过学java的时候&#xff0c;都是在service里直接调用dao&#xff0c;service里面就new一个dao类对象&#xff0c;调用&#xff0c;其他有意义的事没做&#xff0c;也不明白有这个有什么用然后百度了一下我们都…

java heapsort_排序算法笔记:堆排序 HeapSort in java

/*** 堆排序* 简述:* 首先使用建立最大堆的算法建立好最大堆&#xff0c;然后将堆顶元素(最大值)与最后一个值交换&#xff0c;同时使得堆的长度减小1 &#xff0c;调用保持最大堆性质的算法调整&#xff0c;使得堆顶元素成为最大值&#xff0c;此时最后一个元素已被排除在外* …

从Java 10中删除的API

在博客文章“ JDK 10 Release Candidate Phase ”中&#xff0c;我研究了JDK 10可能包含的十二个新功能。 在本文中&#xff0c;我介绍了一些可能会在JDK 10中删除的API&#xff0c;并探讨了一些在JDK 10中建议弃用的API。本文中的信息基于当前版本&#xff08;2018/1 / “ Jav…

使用java自带的日志管理_java日志管理

1.相关概念日志统一框架(日志门面)&#xff1a;apache commons logging、slf4j日志实现框架(实现层)&#xff1a;JDK自带的logging(java.util.logging)、log4j、Java Util Logging、log4j2、logback.(1)JDK自带的logging(java.util.logging)用法&#xff1a;1 importjava.util.…

在会话中使用JWT

在黑客新闻&#xff0c;reddit和博客上&#xff0c;该主题已经讨论了很多次。 共识是–请勿使用JWT&#xff08;用于用户会话&#xff09;。 而且我在很大程度上同意对JWT的典型论点 &#xff0c; 典型的“但我可以使其工作……”的解释以及JWT标准的缺陷的批评 。 。 我不会…

java案例源代码_求java案例源代码 越多越好!

展开全部import java.awt.*;import java.awt.event.*;import java.lang.*;import javax.swing.*;public class Counter extends Frame{//声明三个面板的布局GridLayout gl1,gl2,gl3;Panel p0,p1,p2,p3;JTextField tf1;TextField tf2;Button b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,…

安卓4.4玩java_Android4.4运行过程中闪退java.lang.NoClassDefFoundError

上周五项目测试时发现一个奇怪的Bug&#xff0c;项目中依赖了一个第三方框架&#xff0c;但是在android4.0-4.4.4之间的系统中运行会直接闪退&#xff0c;抛出错误异常为java.lang.NoClassDefFoundError。第一次遇到这样的问题&#xff0c;google了好久找到了以下几个原因&…

java method方法_Java Method.getTypeParameters方法代碼示例

import java.lang.reflect.Method; //導入方法依賴的package包/類private void validateRuleMethod(MethodRuleDefinition, ?> ruleDefinition, Method ruleMethod, RuleSourceValidationProblemCollector problems) {if (Modifier.isPrivate(ruleMethod.getModifiers())) …

update se_Java SE 7 Update 25 –发行说明进行了解释。

update se昨天是CPU日。 Oracle通过6月的Java重要补丁更新发布了Java SE更新25 。 在4月的最后一次重大更新之后&#xff0c;这是最后一次与Oracle其他所有Oracle产品都不适合的Oracle重要补丁更新计划。 从2013年10月开始 &#xff0c;Java安全修补程序将遵循四个年度安全发布…

java scavenge_请概述一下Java中都有哪些垃圾收集器

1、Serial(串行GC)收集器Serial收集器是一个新生代收集器&#xff0c;单线程执行&#xff0c;使用复制算法。它在进行垃圾收集时&#xff0c;必须暂停其他所有的工作线程(用户线程)。是Jvmclient模式下默认的新生代收集器。对于限定单个CPU的环境来说&#xff0c;Serial收集器由…

Java中的异步等待

编写异步代码很困难。 试图了解异步代码应该做什么的难度更大。 承诺是尝试描述延迟执行流程的一种常见方式&#xff1a;首先做一件事&#xff0c;然后再做另一件事&#xff0c;以防万一出错再做其他事情。 在许多语言中&#xff0c;承诺已成为协调异步行为的事实上的方法。 J…

java web ssh启动运行程序_[javaweb开发SSH] myeclipse启动tomcat时的bug

以前用的是myeclipse10.0的版本,我也不知道以前设置了什么,比较正常.由于以前的myeclipse无法装svn,所以装了一个10.7当连接数据库正常时,自然是好的一旦连接数据库不正常了(我故意将数...以前用的是myeclipse10.0的版本, 我也不知道以前设置了什么,比较正常.由于以前的myeclip…

java简单文本编译器_java -简易文本编辑器

import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.io.*;/*** Title:java -简易文本编辑器 ** Description: 08.5.5 简易功能* 1。 打开文件时&#xff0c;无法选择文件&#xff0c;需手动输入* 2. 文件大小超出 多行文本域时&#xff0c;未实现滚动…