如果有更好的方法可以解决这个问题(很有可能(,请告诉我如何去做。
我正在研究一些代码,这些代码应该将表单变量动态设置为常规变量,这样我们就可以偷懒,而不必使用 form.somevariable 名称引用变量。
这部分工作得很好。 直到我开始测试URL变量具有相同名称的URL冲突。 例如。。。
我有一个传递两个变量的表单;名字和姓氏。 如果我点击页面,则会显示表单,我输入名字和姓氏,然后单击提交。 代码运行完美。
但是,如果我有同名的 URL 变量,代码将报告 url 变量值而不是表单值。
一些样本值;
网址。名字 = 乔
网址。姓氏 = 黑色
形式。名字 = 史蒂夫
形式。姓氏 = 白色
我公开表单变量的代码将正确找到表单字段名称,但是当我"评估"给定表单字段的值时,它将返回同名的 URL 变量的值,而不是表单变量。
我真正想要的(正如我上面简要描述的那样(是拥有自动将客户端、URL 和表单变量转换为"常规变量"的代码,这样您以后就不必编写大量额外的代码来抓取它们。 像CFWHEELS和ColdBox这样的框架默认这样做,但在我工作的公司,我们没有使用它们中的任何一个。 我需要它来公开 URL 变量,但如果它们具有相同的名称,则赋予表单变量以主持,因为它们可能旨在进行更新等。
代码如下 如果您愿意,可以随意忽略 URL 和客户端变量的代码,因为它们不会直接影响表单代码的工作方式,我已经将它们注释掉并进行了测试,我得到了相同的结果。 我提供了所有这些内容,以便更全面地了解到目前为止我一直在玩的东西。 请注意,我通常不使用"评估"。 可能有更好的方法,但我不知道它是什么。
++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 名字 姓网址变量:
<cfloop index="i" list="#paramsurl#">
<cfset myDynVar = Evaluate(i)>
<!--- Let's output the dynamically created variable as a test --->
#i# = #myDynVar#<br />
</cfloop>
<cfoutput>
<b>Field Names:</b> #Form.FieldNames#
<p>
<b>Field Values:</b><br>
<cfloop INDEX="TheField" list="#Form.FieldNames#">
#TheField# = #Evaluate(TheField)#<br>
<cfset TheField = Evaluate(TheField)>
</cfloop>
</p>
Lets try and output the two form fields without using the "form." notation<br>
FirstName : #FirstName# <br />
LastName : #LastName#
</cfoutput>
当前可用的客户端变量是:
<cfset nVarCounter = 1>
<cfloop list="#GetClientVariablesList()#" index="whichClientVar">
#whichClientVar# : #client[whichClientVar]#<br />
<cfset whichClientVar = Evaluate(whichClientVar)>
</cfloop>
您应该始终限定变量的范围。使用评估时,它会按范围顺序运行,并在到达form
范围之前将值拉出url
范围
您可以使用关联数组表示法来拉取数据(如下所示(。
<cfoutput>
<b>Field Names:</b> #Form.FieldNames#
<p>
<b>Field Values:</b><br>
<cfloop INDEX="TheField" list="#Form.FieldNames#">
#TheField# = #form[TheField]#<br><!--- specify form scope --->
<cfset myField = structKeyExists(url,TheField) ? url.TheField : form.TheField>
</cfloop>
</p>
</cfoutput>
structAppend(( 将值从form
范围和url
范围"复制到"variables
作用域中。
structAppend( variables, form, true );
structAppend( variables, url, false );
在第一行中,表单范围的任何元素都将复制到变量范围,如果变量作用域中已存在具有相同名称的变量,它将用表单作用域中的值覆盖该值。
在第二行中,来自 URL 范围的元素被复制到变量范围,但如果变量范围中已存在变量,则不会覆盖该变量。
您可以对任何示波器和任何其他 ColdFusion 结构执行此操作。还可以对它们重新排序,以便一个作用域优先于其他作用域。
在 CF 10 或 Railo 4 中,您可以使用 Underscore.cfc 库的defaults()
函数简洁地完成您正在尝试执行的操作。 示例:
// instantiate Underscore library
_ = new Underscore();
// copy values from form and url scopes into the variables scope
_.defaults(variables, form, url);
此函数将第一个结构中的任何未定义值"填充"到后续结构中的值。它从左到右工作,因此在此示例中,它赋予form
中的值优先于url
中的值。
免责声明:我写了Underscore.cfc库。
有关优先级顺序,请参阅以下 Adobe 文档:http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec09af4-7fdf.html
如果您出于某种原因想要反转此优先级,您应该能够将所有 FORM 字段设置为变量范围......
也许像...
<cfloop collection=#form# item="varName">
<cfset SetVariable("variables.#varName#", evaluate("FORM." & varName))>
</cfloop>
感谢所有伟大的想法。
以下是我最终要做的事情。
<cfset scopes = "url,client,form">
<cfloop list="#scopes#" index="i">
<cfloop list="#structKeyList( evaluate( i ) )#" index="j">
<cfset structInsert( VARIABLES, j, evaluate( i & '["' & j & '"]' ), true ) />
</cfloop>
</cfloop>
<cfoutput>
Lets try and output the two form fields without using the "form." notation and make sure that the URL variables are NOT over writing the Form ones<br>
FirstName : #FirstName# <br />
LastName : #LastName#<br />
</cfoutput>
<cfdump var="#VARIABLES#" abort="1" label="Combined Variables Scope stuff" />