此问题的完整重复案例在我的GitHub repository中。我只会在这里重现必要的位。
假设我使用了一些自定义标签:
<!--- testCfcTags.cfm --->
<cfimport taglib="cfcBasedTags" prefix="t">
Text before tags<br>
<t:grandparent gp:attr="set in grandparent">
Text in grandparent, before parent<br>
<t:parent p:attr="set in parent">
Text in parent, before child<br>
<t:child c:attr="set in child">
Text in child<br>
</t:child>
Text in parent, after child<br>
</t:parent>
Text in grandparent, after parent<br>
</t:grandparent>
Text after tags<br>
如果我使用基于CFM的自定义标记,并且我想要将child
标记的实现中的数据与grandparent
标记相关联,我只想这样做:
<!--- child.cfm --->
<cfif thistag.executionMode eq "end">
<cfassociate basetag="cf_grandparent" datacollection="childAttributesForGrandparent"><!--- this line --->
<cfassociate basetag="cf_parent" datacollection="childAttributesForParent">
</cfif>
注意我可以直接与祖父母标记相关联。
我无法弄清楚如何使用Lucee的基于CFC的自定义标记干净地 。
这是我能想到的最好的:
// Child.cfc
component {
function init(hasEndTag, parent){
this.parent = arguments.parent;
}
function onEndTag(attributes, caller, generatedContent){
writeOutput(generatedContent);
this.parent.childattributesForParent = attributes;
this.parent.parent.childattributesForGrandparent = attributes;
return false;
}
}
在Parent.cfc中我有这个:
// Parent.cfc
component {
function init(hasEndTag, parent){
this.parent = arguments.parent;
}
function onEndTag(attributes, caller, generatedContent){
writeOutput(generatedContent);
this.parent.parentattributesForGrandparent = attributes;
writeDump(var=this.childAttributesForParent, label="Parent childAttributesForParent");
return false;
}
}
父母和祖父母的this
范围的累积(错误)使用意味着来自儿童,我可以通过this.parent.parent
将内容直接打入祖父母。
然而,这有点“Heath Robinson”。鉴于Lucee的其他基于CFC的自定义标签实现非常灵活,我相信我只是缺少一些东西。我真的不认为我应该通过父母来挖掘祖父母。此外,它意味着代码需要在Child直接在祖父母中的情况下有所不同。我真正需要的是一些标签层次结构在CFC之间传递,而不仅仅是父级。
我已经开始搜索了,但是大部分内容都是由我编写的(反过来是基于最初为Railo实现此目的而写的博客文章 - 这是Lucee实现的基础)。
我已经阅读的文档,没有任何帮助:
答案 0 :(得分:2)
根据Railo博客:
http://blog.getrailo.com/post.cfm/cfc-based-custom-tags-by-example-part-1
您可以使用标签cfassociate和函数GetBaseTagList以及&gt; GetBaseTagData,方法与常规基于CFML的自定义标签相同。
所以你可以(在cfscript中):
cfassociate(basetag="cf_grandparent", datacollection="childAttributesForGrandparent");
我把一些样本放在一起 - 我已经测试并验证它适用于Lucee 4.5.1: https://gist.github.com/dajester2013/183e862915972d51279f
根据我的评论,这是一个通过基础标记的潜在方法 - 它至少掩盖了不那么漂亮的方面:
BaseTag.cfc
component accessors=true {
property name="tagName";
property name="parent";
property name="hasEndTag";
public BaseTag function init() {
structAppend(variables, arguments);
tagName = "cf_" & lcase(listLast(getMetaData(this).fullname,"."));
return this;
}
public any function getParent(string tagName, ancestors=1) {
if (!isNull(tagName)) {
var data = getBaseTagData(tagName, ancestors);
if (structKeyExists(data,"thisTag")) {
return data.thisTag;
// getBaseTagData returns the variables scope for CFC tags...
} else if (structKeyExists(data, "this")) {
return data.this;
}
} else if (!isNull(variables.parent)) {
return variables.parent;
}
}
private void function associate(required string tagName, string dataCollection=this.getTagName()) {
cfassociate(basetag=tagname, dataCollection=dataCollection);
}
}
TestChild.cfc
component extends=BaseTag {
public function onStartTag() {
attributes._childId = randrange(1000,9000);
associate("cf_testtag", "testchildren");
writedump(var=this.getParent(),label='immediateparent');
writedump(var=this.getParent("cf_testtag"), label='testtag');
abort;
}
}