2

我的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: line 21
Called from C:\path\to\document\root\cfc\update-emp.cfm: line 66
Called from C: \C:\path\to\document\root\cfc\update-emp.cfm:第 66 行

19 : 21 : 23`: : <cfif key eq "#arguments.structstring#">
20

: <cfset y = evaluate(0,key) />
22

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

4

2 回答 2

7

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

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

但你也有其他问题。对于初学者来说,当您将代码移入 CFC 时,您并没有正确地复制逻辑。

在您的工作代码中,您使用条件:

<cfif left(key,4) eq "UPD_">

但是在您的 CFC 中,您有:

<cfif key eq arguments.structString>

这应该是:

<cfif left(key,4) eq arguments.structString>

接下来,您没有使用最佳语法进行评估,您可能根本不想使用它。该声明:

y = evaluate(0,key)

可以改写为:

y = evaluate(key)

由于 key 的值为“UPD_something”,因此可以重写为:

y = [variables|arguments|etc].UPD_Something

(由于您没有明确指定变量范围,CF 将尝试按特定顺序在一组范围中查找变量;这就是我使用语法 [a|b|...] 的原因)

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

y = variables.instance.form[key]

我认为这可能会解决它。所以,总结一下:

  1. 将您的语句替换<cfif key eq arguments.structString><cfif left(key,4) eq arguments.structString>(并确保您作为“structString”传递的值包括下划线!)

  2. 将您的使用替换为evaluatey = variables.instance.form[key]

我希望能解决你的问题...

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

于 2009-06-30T14:07:12.207 回答
3

我完全同意 Adam Tuttle 的帖子。我已经删除了答案中的“解决方案部分”部分,以支持他。所以这是我关于“一般部分”的两分钱:

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

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

等于:

<cfset foo = FORM[foo]>

所有“方便”的误用Evaluate()都可以这样解决。

还有一些提示:

  • 避免使用无意义的变量名称,例如“x”或“y”(当然,除非您引用 2D 坐标)。
  • 不要这样做"#variable#"- 您可以简单地使用variable
  • 当您需要使用键访问项目时,请尽可能使用结构,例如,
    <cfif array[i][1] eq SomeValue>优雅程度不如
    <cfif array[i]["FieldName"] eq SomeValue>
  • 你真的不需要“ variables.instance”——每个组件实例都有它自己的VARIABLES范围。默认情况下,无论您坚持什么,都是“仅限实例”。
  • 无需将FORM范围传递给组件。范围是全球性的,因此 CFC 无论如何都可以看到它。
  • 为什么将数据库内容存储在一个额外的数组中,而不是使用检索它们时获得的 Query 对象?
  • 无需自关闭 ( "/>") CFML 语句 - 您不是在编写 XML(尽管这是个人喜好问题)。
于 2009-06-30T15:24:21.677 回答