如何使自定义标记中的代码块仅在第一次调用该标记时运行?

发布于 2024-07-16 12:55:12 字数 2039 浏览 6 评论 0原文

我正在创建一组 ColdFusion 自定义标签,旨在轻松重用某些布局元素。 我将以类似于以下的方式使用它们:

<cfimport prefix="layout" taglib="commonfunctions/layouttags">

<layout:fadingbox>
    This text will fade in and out
</layout:fadingbox>
<layout:stockticker>
    This text will scroll across the screen
</layout>

为了使这些自定义标签生成的代码能够工作,需要将 JavaScript 文件链接到页面中,如下所示:

<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>

我更愿意包含来自自定义标签,而不是让用户自己添加它。 问题是每个页面只能包含 JavaScript 文件一次。 第一次使用这些自定义标签之一后,我希望后续调用同一页面上的同一标签,以避免重复

<cfif NOT isDefined("Caller.LayoutTagInitialized")>
    <script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
</cfif>
<cfset Caller.LayoutTagInitialized = 1>

……但这看起来不优雅。

我想知道,还有更好的办法吗?

你会如何实施这个?

编辑 - 说明:

如果我上面写的内容没有意义,这里有一个更详细的示例:

如果我有一个像这样的自定义标签:

<cfif ThisTag.ExecutionMode EQ "start">
    <script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
    <div class="mytag">
<cfelse>
    </div>
</cfif>

...并且我有 CFML 标记调用该标签,例如像这样:

<layout:mytag>
    One
</layout:mytag>
<layout:mytag>
    Two
</layout:mytag>
<layout:mytag>
    Three
</layout:mytag>

...我想要生成如下 HTML:

<!-- Script included only the first time the tag is called -->
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
<div class="mytag">
    One
</div>
<!-- No <script> tag on the second call -->
<div class="mytag">
    Two
</div>
<!-- No <script> tag on the third call -->
<div class="mytag">
    Three
</div>

I'm creating a set of ColdFusion custom tags designed to make reusing certain layout elements easy. I'll be using them in a manner similar to the following:

<cfimport prefix="layout" taglib="commonfunctions/layouttags">

<layout:fadingbox>
    This text will fade in and out
</layout:fadingbox>
<layout:stockticker>
    This text will scroll across the screen
</layout>

In order for the code these custom tags generates to work, a JavaScript file needs to be linked into the page like so:

<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>

I'd prefer to include the script from inside the custom tags, instead of making the user include it himself. The issue is that the JavaScript file should only be included once per page. After the first time one of these custom tags is used, I'd like subsequent calls to the same tag on the same page to avoid repeating the <script> tag. It's occurred to me that I could do something like this:

<cfif NOT isDefined("Caller.LayoutTagInitialized")>
    <script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
</cfif>
<cfset Caller.LayoutTagInitialized = 1>

...but it seems inelegant.

I wonder, is there a better way?

How would you implement this?

Edit - Clarification:

In case what I wrote above didn't make sense, here's a more detailed example:

If I have a custom tag like this:

<cfif ThisTag.ExecutionMode EQ "start">
    <script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
    <div class="mytag">
<cfelse>
    </div>
</cfif>

...and I have CFML markup calling the tag like like this:

<layout:mytag>
    One
</layout:mytag>
<layout:mytag>
    Two
</layout:mytag>
<layout:mytag>
    Three
</layout:mytag>

...I want HTML like the following to be generated:

<!-- Script included only the first time the tag is called -->
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
<div class="mytag">
    One
</div>
<!-- No <script> tag on the second call -->
<div class="mytag">
    Two
</div>
<!-- No <script> tag on the third call -->
<div class="mytag">
    Three
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

原野 2024-07-23 12:55:12

使用请求范围。

Use the Request scope.

眼泪也成诗 2024-07-23 12:55:12

您的解决方案并不遥远。

Sam 是对的,当您希望某些内容以标签的开始或结束模式出现时,执行模式就是您想要使用的,这是您想要的一部分。

但是,您又说您希望将该脚本标记放在页面上使用的第一个标记的启动模式中。

这就是您可以使用 Peter 关于请求范围的建议的地方。 与默认(或“变量”)范围不同,请求范围在给定请求的所有自定义标记之间共享。 您建议使用调用者范围,这也可以工作,除非调用者是另一个自定义标记,在这种情况下,调用者范围将只是自定义标记中的本地范围。 请求范围(从 CF 4.01 开始就存在)是您的最佳选择。

在这种情况下,您提出的解决方案很接近:在自定义标记中,在启动模式下,当您第一次放置脚本标记时,以编程方式检查是否已经在请求范围中创建了跟踪变量。 如果没有,则输出脚本标签并创建跟踪变量。

除了更改使用调用者请求的代码之外,我还建议您将 CFSET 放在 IF 内。 IF测试失败时无需再次执行。

Your solution isn't far off.

Sam's right that the executionmode is what you want to use when you're wanting something to come out in the start or end mode of the tag, which is part of what you want.

But then you say you want that script tag put out in the start mode of only the first tag used on the page.

That's where you would use Peter's suggestion of the request scope. Unlike the default (or "variables") scope, the request scope is shared among all custom tags on a given request. You proposed using the caller scope, and that could work, too, unless the caller was another custom tag, in which case the caller scope would only be the local scope in the custom tag. The request scope (which has been around since about CF 4.01) is your best choice.

In that case, your proposed solution was close: in the custom tag, in the start mode, programatically check if you have already created a tracking variable in the request scope when you put the script tag out the first time. If not, put out the script tag and create the tracking variable.

Other than changing your code from using caller to request, I'd also suggest you'd want to put the CFSET inside the IF. No need to execute it again for when the IF test fails.

一片旧的回忆 2024-07-23 12:55:12

自定义标签有一个名为 thistag 的内置范围。

这段代码将起作用:

<cfif thisTag.ExecutionMode eq "start">

Custom tags have a built in scope called thistag.

This code will work:

<cfif thisTag.ExecutionMode eq "start">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文