Data structures 通过结构的ColdFusion循环和密钥计算失败!我错过了什么?

Data structures 通过结构的ColdFusion循环和密钥计算失败!我错过了什么?,data-structures,coldfusion,loops,evaluation,Data Structures,Coldfusion,Loops,Evaluation,我的cfm中有这个代码,它可以工作 <cfif not StructIsEmpty(form)> <cfset larray = user.getArray() /> <cfloop collection="#form#" item="key"> <cfif left(key,4) eq "UPD_"> <cfset x = listLast(key,"_") /> <cfset y = evaluate(0,

我的cfm中有这个代码,它可以工作

<cfif not StructIsEmpty(form)>
 <cfset larray = user.getArray() />
 <cfloop collection="#form#" item="key">
  <cfif left(key,4) eq "UPD_">
   <cfset x = listLast(key,"_") />
   <cfset y = evaluate(0,key) />
   <cfloop index="j" from="1" to="#arrayLen(larray)#">
    <cfif (larray[j][1] eq x) and (larray[j][3] neq y)>
     <cfset larray[j][3] = y />
     <cfif not LSIsNumeric(larray[j][3])>
      <cfset larray[j][3] = "0" />
     </cfif>
     <cfset larray[j][4] = "update" />
    </cfif>
   </cfloop>
  </cfif>
 </cfloop>

 <cfloop collection="#form#" item="key">
  <cfif left(key,4) eq "DEL_">
   <cfset x = listLast(key,"_") />
   <cfloop index="k" from="1" to="#arrayLen(larray)#">
    <cfif larray[k][1] eq x>
     <cfset larray[k][4] = "delete" />
    </cfif>
   </cfloop>
  </cfif>
 </cfloop>

 <cfset user = createObject("component", "cfc.User").init(
    identifier = FormatBaseN(form.id,10),
    array = larray
    ) />
</cfif>

<form name="usform" method="POST">
<cfset array = user.getArray() />
<cfoutput>
<cfloop index="i" from="1" to="#arrayLen(array)#">
<table>
 <tr>
  <td><input type="text" name="upd_#array[i][1]#" maxlength="6" size="6" value="#array[i][3]#" /></td>
  <td><input type="checkbox" name="del_#array[i][1]#" /></td>
 </tr>
</table>
<input type="hidden" name="id" value="#user.getIdentifier()#" />
</cfoutput>
</form>

我已经把它放进了cfc中,以分离我的逻辑和我的观点,我正在努力使它更通用

<cfcomponent name="ArrayManager" output="false">
 <cffunction name="init" hint="constructor" output="false" returntype="ArrayManager">
  <cfargument name="user" type="User" required="true" hint="User bean" />
  <cfargument name="form" type="Struct" required="true" />
  <cfset variables.instance.array = arguments.user.getArray() />
  <cfset variables.instance.form = arguments.form />
  <cfreturn this />
 </cffunction>

 <cffunction name="update" access="public" output="true" returntype="boolean">
  <cfargument name="structstring" type="String" required="true" />
  <cfargument name="seperator" type="String" required="true" />
  <cfset var x = "0" />
  <cfset var y = "0" />
  <cfloop collection="#variables.instance.form#" item="key">
   <cfif key eq "#arguments.structstring#">
    <cfset x = listLast(key,"#arguments.seperator#") />
    <cfset y = evaluate(0,key) />
    <cfloop index="j" from="1" to="#arrayLen(variables.instance.array)#">
     <cfif (variables.instance.array[j][1] eq x) and (variables.instance.array[j][3] neq y)>
      <cfset variables.instance.array[j][3] = y />
      <cfif not LSIsNumeric(variables.instance.array[j][3])>
       <cfset variables.instance.array[j][3] = "0" />
      </cfif>
  <cfset variables.instance.array[j][4] = "update" />
 </cfif>
</cfloop>
   </cfif>
  </cfloop>
  <cfset arguments.user.init(array = variables.instance.array) />
  <cfreturn true />
 </cffunction>

 <cffunction name="delete" access="public" output="false" returntype="boolean">
  <cfargument name="structstring" type="String" required="true" />
  <cfargument name="seperator" type="String" required="true" />
  <cfset var x = "0" />
   <cfloop collection="#variables.instance.form#" item="key">
    <cfif key eq "#arguments.structstring#">
     <cfset x = listLast(key,"#arguments.seperator#") />
     <cfloop index="k" from="1" to="#arrayLen(variables.instance.array)#">
      <cfif variables.instance.array[k][1] eq x>
       <cfset variables.instance.array[k][4] = "delete" />
      </cfif>
     </cfloop>
    </cfif>
   </cfloop>
  <cfset arguments.user.init(array = variables.instance.array) />
  <cfreturn true />
 </cffunction>
</cfcomponent>

还有我的新cfm

<cfif not StructIsEmpty(form)>
 <cfset arraymanager = createObject("component","cfc.ArrayManager").init(user,form) />
 <cfset seperator = "_" />
 <cfset structstring = "UPD" />
 <cfset arraymanager.update(structstring,seperator) />
</cfif>
...

...
如果失败,我将收到此错误消息

CFML编译器遇到意外的coldfusion.compiler.CompilerInternalException异常。 原因是:无法完成CFML到Java的转换。发生于:

。 .

错误出现在C:\path\to\document\root\cfc\ArrayManager.cfc:第21行
从C:\path\to\document\root\cfc\update-emp.cfm调用:第66行
从C:\C:\path\to\document\root\cfc\update-emp.cfm调用:第66行

19

20

21

22

23`:


我做错了什么,或者是否有更好的方法来完成我试图做的事情(在表中显示数据库内容,并通过同一个表更新(更新和删除)数据库内容)

您发布的错误消息表明您误用了该功能。根据文档,它的工作原理如下:

从左到右动态计算一个或多个字符串表达式。(左侧的计算结果在右侧的表达式中可能有意义。)返回最右侧表达式的计算结果

但你也有其他问题。首先,当您将代码移动到CFC中时,您没有正确地复制逻辑

在工作代码中,可以使用条件:

<cfif left(key,4) eq "UPD_">
可以重写为:

y = evaluate(key)
y = [variables|arguments|etc].UPD_Something
由于key的值为“UPD_something”,因此可以重写为:

y = evaluate(key)
y = [variables|arguments|etc].UPD_Something
(由于没有显式指定变量作用域,CF将尝试按特定顺序在一组作用域中查找变量;这就是我使用语法[a | b |……]的原因)

您可能不是这个意思,您可能希望表单中的值。而且,由于键名是动态的,您应该以这种方式访问它(而不是使用
evaluate
):

我想那可以解决它。因此,总结一下:

  • 将语句
    替换为
    (并确保作为“structString”传递的值包含下划线!)

  • evaluate
    替换为:
    y=variables.instance.form[key]

  • 我希望这能解决你的问题


    在它工作之后,开始考虑变量名。“Array”是一个糟糕的变量名,因为它实际上是CFML中的一个保留字。使用“x”和“y”根本不是描述性的。这些问题使得这个问题很难回答。

    我完全同意亚当·塔特尔的观点。我删除了答案中的“解决方案”部分,取而代之的是他的答案。这是关于“一般部分”的两分钱:

    完全避免
    Evaluate()
    是最好的选择。除了实际评估代码片段(这是另一个应该避免的伤害)之外,没有理由使用它。如果这不是您正在做的事情,那么没有比
    Evaluate()
    更合适的方法无法解决的情况,例如:

    <cfset foo = Evaluate("FORM.#foo#")>
    
    
    
    等于:

    <cfset foo = FORM[foo]>
    
    
    
    Evaluate()
    的所有“方便性”误用都可以这样解决

    还有一些提示:

    • 避免使用“x”或“y”等无意义的变量名(当然,除非您使用的是二维坐标)
    • 不要使用
      “#变量#”
      -您只需使用
      变量
    • 当需要使用密钥访问项目时,尽可能使用结构,例如
      远不如
    • 您实际上不需要“
      变量。实例”
      ”-每个组件实例都有自己的
      变量范围。默认情况下,无论您坚持什么,都是“仅实例”
    • 无需将
      表单
      范围传递给组件。这个范围是全球性的,所以CFCs无论如何都可以看到它
    • 为什么要将数据库内容存储在一个额外的数组中,而不是使用检索它们时得到的查询对象
    • 无需自行关闭(
      “/>”
      )CFML语句—您并不是在编写XML(尽管这是一个品味问题)

    我已经试着对你的代码绞尽脑汁一段时间了。我不知道如何推断缺失的部分。您使用的是什么数据结构?这张表格是什么样子的?你为什么把所有的东西都放在嵌套数组里?我和Tomalak在一起。你想干什么?具体来说,你希望从中得到什么?我认为这是用来表示“”-但老实说,我认为这在很多方面都是站不住脚的。+1非常好。我已经准备好了类似的东西,但是当我完全理解了原始代码的目的后,我变得不安全,我犹豫是否发布它。我想我会发布建议部分。我不同意关于传递表单范围的部分。我认为这是将组件与使用它的页面解耦的一部分。应用程序范围、会话范围等也是如此(99%的时间)。。。一般来说,您不应该直接从CFC访问它们。我也喜欢XML/XHTML格式的CFML标记,但正如您所说,这是开发人员的风格选择。我发现当一个标签在一个深度嵌套的情况下有或没有孩子时,它们会使它变得更加明显;尤其是当一个同级的IDE干扰了你的缩进时。嗯,我个人认为
    <cfset foo = Evaluate("FORM.#foo#")>
    
    <cfset foo = FORM[foo]>