如果有更好的方法(很可能),请告诉我如何解决这个问题。
我正在研究一些应该将表单变量动态设置为常规变量的代码,这样我们就可以变得懒惰而不必使用form.somevariable名称来引用该变量。
那部分完美无缺。直到我开始测试URL变量具有相同名称的URL冲突。例如。 。
我有一个传递两个变量的表单; FirstName和LastName。如果我点击页面,表单会显示,我输入名字和姓氏,然后点击提交。代码完美无缺。
但是,如果我有相同名称的URL变量,代码会报告url变量值而不是表单值。
一些样本值;
url.FirstName = Joe
url.LastName = Black
form.FirstName = Steve
form.LastName = White
我公开表单变量的代码将正确地找到表单字段名称,但是当我'评估'给定表单字段的值时,它将返回同名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>
答案 0 :(得分:4)
您应始终确定变量的范围。当您使用评估时,它会在scope order中运行,并且会在url
范围之前将值拉出form
范围
您可以使用关联数组表示法来提取数据(如下所示)。
<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>
答案 1 :(得分:2)
您可以使用structAppend()将form
范围和url
范围内的值'复制'到variables
范围。
structAppend( variables, form, true );
structAppend( variables, url, false );
在第一行中,表单作用域的任何元素都被复制到变量作用域,如果变量作用域中已存在同名的变量,它将使用表单作用域中的值覆盖该值。
在第二行中,元素形式的URL范围被复制到变量范围,但如果变量范围中已存在变量,则不会覆盖它。
您可以为任何范围和任何其他ColdFusion结构执行此操作。您也可以对它们进行重新排序,以便一个范围优先于其他范围。
答案 2 :(得分:0)
在CF 10或Railo 4中,您可以使用Underscore.cfc library的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库。
答案 3 :(得分:-1)
有关优先顺序,请参阅以下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>
答案 4 :(得分:-2)
感谢所有好主意。
以下是我最终的目标。
<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" />