日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

多个动态包含一个JSF标签

發(fā)布時(shí)間:2023/12/3 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多个动态包含一个JSF标签 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

每個(gè)JSF開(kāi)發(fā)人員都知道ui:include和ui:param標(biāo)簽。 您可以包括一個(gè)facelet(XHTML文件)并傳遞一個(gè)對(duì)象,該對(duì)象將在包含的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}表示描述這些列的特殊對(duì)象的列表。 我將此類對(duì)象命名為ColumnModel。 所以,這是一個(gè)
列出<ColumnModel>。 ColumnModel具有例如屬性標(biāo)頭和屬性。

繼續(xù)。 現(xiàn)在,如果要添加對(duì)排序/過(guò)濾的支持,我們可以使用動(dòng)態(tài)路徑,該路徑引用包含排序或/和過(guò)濾功能的特定facelet文件。 簡(jiǎn)單地將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";} }

根據(jù)所設(shè)置的布爾權(quán)限,包含了不同的方面。 因此,將要包含的文件的決定放在Bean中。 為了更加靈活,我們可以將表封裝在一個(gè)復(fù)合組件中,并將決策邏輯移至組件類。

<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如何工作? 這是在構(gòu)建視圖時(shí)應(yīng)用的標(biāo)記處理程序。 在JSF 2中,組件樹根據(jù)POST請(qǐng)求構(gòu)建兩次,一次在RESTORE_VIEW階段,一次在RENDER_RESPONSE階段。 在GET上,它在RENDER_RESPONSE階段構(gòu)建一次。 此行為在JSF 2規(guī)范中指定,并且在Mojarra和MyFaces中相同。 如果頁(yè)面作者使用條件包含或條件模板,則必須在RENDER_RESPONSE中建立視圖。 因此,您可以確保ui:include的src屬性在呈現(xiàn)階段之前不久就得到了評(píng)估。

但是到了重點(diǎn)! 到目前為止,我所寫的內(nèi)容只是介紹了擴(kuò)展ui:include的動(dòng)機(jī)。 最近,我有一項(xiàng)任務(wù)要使用帶有動(dòng)態(tài)列的ap:dataTable和p:rowEditor。 在PrimeFaces展示柜中就是這樣的 。 問(wèn)題只是–這種編輯功能不支持p:columns。 我的想法是動(dòng)態(tài)地多次添加p:column標(biāo)簽,但是具有不同的上下文參數(shù)。 您可以將其想象為ui:include和ui:param在循環(huán)中。 在上面的示例中,我們打算遍歷List <ColumnModel>。 每次循環(huán)迭代都應(yīng)在所包含的facelet中提供ColumnModel類型的實(shí)例。 因此,我編寫了一個(gè)自定義標(biāo)簽處理程序以多次包含任何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);}} }

最重要的調(diào)用是ctx.includeFacelet(parent,path)。 JSF API中的 includeFacelet(…)方法在相對(duì)于當(dāng)前標(biāo)記的某個(gè)路徑上包含了facelet標(biāo)記。 類VariableMapperWrapper用于通過(guò)ui:param從名稱到值的映射。 對(duì)于帶有列的示例,在每次調(diào)用includeFacelet(...)之前,變量列還將映射到表達(dá)式#{columns [0]},#{columns [1]}等。 好吧,不完全是這些表達(dá)式,在列的位置應(yīng)該是一個(gè)唯一的名稱,該名稱再次映射到columns對(duì)象(以避免可能的名稱沖突)。 映射器類如下所示

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文件中注冊(cè)標(biāo)簽處理程序,您就可以完成。

<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>

現(xiàn)在我可以在復(fù)合組件中使用它了

<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文件(和組件樹)包含一個(gè)非常規(guī)則的p:column標(biāo)記,這意味著我們能夠使用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>

注意 :此方法可以應(yīng)用于其他組件和用例。 InlcudesTagHandler可以正常運(yùn)行。 例如,我可以想象在沒(méi)有基礎(chǔ)MenuModel的情況下在PrimeFaces中創(chuàng)建一個(gè)動(dòng)態(tài)Menu組件。 當(dāng)然,仍然需要某個(gè)模型類的列表或數(shù)組。

參考:在我們的軟件開(kāi)發(fā)博客上, JCG合作伙伴 Oleg Varaksin的一個(gè)JSF標(biāo)簽包含了多個(gè)動(dòng)態(tài) 。

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

總結(jié)

以上是生活随笔為你收集整理的多个动态包含一个JSF标签的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。