将会话从CFScript转换为ColdFusion标记语法

将会话从CFScript转换为ColdFusion标记语法,coldfusion,coldfusion-8,cfml,Coldfusion,Coldfusion 8,Cfml,应用程序:JavaScript函数侦听表单元素的更改(输入和选择),并将数据发布到CFC方法,该方法将数据分配给会话结构。返回结构,使表单数据在会话生命周期内可用。该应用程序根据上的代码进行了改编 问题:原始CFC代码是用CFScript编写的。因为我们使用的是ColdFusion 8,所以在调用该方法时出现了一个错误。因此,我将该方法转换为ColdFusion标记语法,并停止了该错误。在Chrome的开发工具中,每次在表单元素中输入内容时,我都可以看到数据通过JSON对象传递到CFC。所以我知

应用程序:JavaScript函数侦听表单元素的更改(输入和选择),并将数据发布到CFC方法,该方法将数据分配给会话结构。返回结构,使表单数据在会话生命周期内可用。该应用程序根据上的代码进行了改编

问题:原始CFC代码是用CFScript编写的。因为我们使用的是ColdFusion 8,所以在调用该方法时出现了一个错误。因此,我将该方法转换为ColdFusion标记语法,并停止了该错误。在Chrome的开发工具中,每次在表单元素中输入内容时,我都可以看到数据通过JSON对象传递到CFC。所以我知道JavaScript函数正在工作。尽管我没有收到任何返回错误,但有一些行为让我相信我的翻译是错误的。例如,会话结构的转储仅显示输入的最后一个输入元素,而不是所有元素(如Ray的演示中所示)

这是CFScript的原始版本,然后是我的标签翻译。除了任何关于我的翻译错误的评论之外,我想对这一行,
,特别是
[s[name]]]
结构进行解释,因为我无法清楚地表达那里发生了什么。谢谢

脚本语法:

component {
    remote void function preserveSession(string awardData) {
        if(!isJSON(arguments.awardData)) return;
        arguments.awardData = deserializeJSON(arguments.awardData);

        //convert the array into a name based struct
        var s = {};
        for(var i=1; i<=arrayLen(arguments.awardData); i++) {
            var name = arguments.awardData[i].name;
            if(!structKeyExists(s, name)) {
                s[name] = arguments.awardData[i].value;    
            } else {
                //convert into an array
                if(!isArray(s[name])) {
                    s[name] = [s[name]];
                }
                arrayAppend(s[name], arguments.awardData[i].value);
            }    
        }
        session.awardFormData = s;    
    }
}
<cfcomponent>
    <cffunction name="preserveSession" access="remote" returntype="void" output="no">

        <cfargument name="awardData" type="string" />

        <cfset var s = {} />

        <cfif NOT isJSON(arguments.awardData)>
            <cfreturn />
        </cfif>

        <cfset arguments.awardData = #deserializeJSON(arguments.awardData)# />

        <cfloop index="i" from="1" to="#arrayLen(arguments.awardData)#">
            <cfset name = #arguments.awardData[i].name# />

            <cfif NOT structKeyExists(s, name)>
                <cfset s.name = #arguments.awardData[i].value# />   
            <cfelse>
                <cfif NOT isArray(s.name) >
                    <cfset s.name = [s[name]] />
                </cfif>
                <cfset arrayAppend(s.name, arguments.awardData[i].value) />
            </cfif>
        </cfloop>

        <cfset session.awardFormData = s />

        <cfreturn />
    </cffunction>
</cfcomponent>
组件{
远程void函数保存会话(字符串awardData){
如果(!isJSON(arguments.awardData))返回;
arguments.awardData=反序列化JSON(arguments.awardData);
//将数组转换为基于名称的结构
var s={};
对于(var i=1;i

您需要动态访问密钥名称。上面的代码每次都使用相同的静态密钥(即
name
),因此每次循环时都会覆盖上一个值。这就是为什么最后只有一个值

 <!--- this creates a dynamic key named "apple" (correct) --->
 <cfset name = "apple" />
 <cfset s[name] = "..." />

 <!--- this creates a key literally named "name" (wrong) --->
 <cfset name = "apple" />
 <cfset s.name = "..." />

要修复它,无论您在哪里使用
s.name
,请将其替换为
s[name]
。此外,不要忘了
var
作用域所有函数局部变量

更新:


这也提出了一个很好的观点。您不必将其全部转换为cfml。将其大部分封装在
cfscript
标记中会更简单。

首先,您不需要翻译所有这些内容。CF8不支持cfscript中的组件/函数,但在其他情况下,您可以按原样使用它:

<cfcomponent>
  <cffunction name="preserveSession" access="remote" returntype="void" output="no">
    <cfargument name="awardData" type="string" />
      <cfscript>
        var s = {};
        var name = '';
        var i = 0;
        if(!isJSON(arguments.awardData)) return false;
        arguments.awardData = deserializeJSON(arguments.awardData);
        for(i=1; i<=arrayLen(arguments.awardData); i++) {
          name = arguments.awardData[i].name;
          if(!structKeyExists(s, name)) {
            s[name] = arguments.awardData[i].value;
          } else {
            if(!isArray(s[name])) {
              s[name] = [s[name]];
            }
            arrayAppend(s[name], arguments.awardData[i].value);
          }
        }
        session.awardFormData = s;
        return true;
    </cfscript>
  </cffunction>
</cfcomponent>

var s={};
变量名=“”;
var i=0;
如果(!isJSON(arguments.awardData))返回false;
arguments.awardData=反序列化JSON(arguments.awardData);

对于(i=1;如果我记得的话,您在CF8中需要做的一件事是将您的var移动到脚本块的顶部。但是,否则,cfscript应该支持所有现代对象表示法。CF9允许您在CF9+中的任何位置使用var。我将对其进行编辑以反映这一点。@williambq-最好将最后一部分添加为,因此它是more可见。然后删除注释。我必须更改一些细节,例如,将循环的“var I=1;”子句移到脚本顶部,并删除结束的“return true;”子句(因为我声明了“returntype=void”)还有,呜呼,我现在得到了会话转储中的所有表单元素。谢谢!谢谢你们两位对s[name]=[s[name]]的解释;这更有意义。