ColdFusion 中的异步形式

Asynchronous Form in ColdFusion

我是 ColdFusion 的新手,希望得到一些建议。我创建了一个超级基本的购物清单程序,我想知道如何在不刷新页面的情况下更新清单。我考虑过将数据从我的 DBMS 导入到一个数组中,然后只显示该数组的内容。除了实际显示数组中的每个项目之外,我还能做所有事情。我收到一个错误:Complex object types cannot be converted to simple values.

这是我的代码:

<body>
    <cfquery datasource="ESC-ADD-TECH" name="items">
        SELECT *
        FROM items
        ORDER BY itemDesc ASC
    </cfquery>

<div id="myDIV" class="header">
    <h2>My Shopping List</h2>
    <cfform  id="new_item">
    <cfinput type="text" name="updateinfo" placeholder="Item..." required="true" />
      <input name="submitButt" type="submit" class="addBtn"></input>
    </cfform>

    <cfset itemsArray = arrayNew(1)>
    <cfset arrayAppend(itemsArray, #items#)>

    <cfif structKeyExists(form, "submitButt")>
    <cfset arrayAppend(itemsArray, #updateinfo#)>

    <cfquery datasource="ESC-ADD-TECH">
    INSERT INTO items(itemDesc) VALUES('#updateinfo#')
    </cfquery>


    </cfif>
</div>

          <cfoutput query="items">  
    <ul>
        <li>#itemsArray#</li>
    </ul>   
          </cfoutput>

</body>

谢谢

(评论太长了....)

;tldr

CF 就像任何其他服务器端网络应用程序语言(asp、asp.net、php 等)。它对客户端代码一无所知。应用服务器解析 CFML(php 代码,asp.net,任何语言...)并返回代码生成的 HTML/CSS/JS。因此,您的 CFML 代码没有理由不能包含 javascript,除非客户明确表示不要使用它。如果他们这样做了,那么是的,刷新列表的唯一方法是重新提交页面。从编码的角度来看,自发布表单更简单,但确实具有非常 1990 年代的用户体验 ;-)

建议:

听起来你很精通javascript,所以你通过ajax操纵DOM应该没有问题。但是,如果您打算改用自发布表单,请对当前的 CF 代码发表一些评论:

  1. 严格来说是一种风格偏好,但将查询和“查看”(或显示)代码分开可以使 IMO 的内容更具可读性。

  2. 为了显示任何新添加的项目,代码必须先执行 INSERT,然后 SELECT 查询。

  3. 'complex object...' 错误是由于 INSERT 查询将数组(复杂)视为简单值(字符串、日期、数字)。 CF 不知道如何将复杂数组“#updateinfo#”隐式转换为字符串。也就是说,您实际上根本不需要数组(请参阅#4)

  4. 您的表单仅包含一个输入字段,因此不需要数组。只需直接插入单个值即可。请记住,最好始终使用 cfqueryparam 来防止 sql 注入。加上它的其他好处,如验证和性能。此外,始终限定变量范围以避免歧义。例如,使用 FORM.updateinfo 而不是 updateinfo

  5. 虽然 <cfform> 有效,但它(以及相关的控件,如 <cfinput> 等)近年来已失宠。主要是因为它嵌入到 CF 中,因此很难更新或自定义行为。

  6. 养成知道何时使用或不使用井号的习惯是很好的。大多数人对他们不需要的频率感到惊讶。有一些例外,但通常只有在以下任一情况下才需要:

    一个。变量用引号括起来。示例:
    b. <cfoutput> 标签

    中包含一个变量
  7. 如果您来自 JavaScript 背景,您可能更喜欢 cfscript 而不是 cfml(标签)。从 CF11+ 开始,几乎所有您在 cfml 中可以做的事情,都可以在 cfscript 中完成。

修改后的脚本

<!--- 1. Add new items --->
<cfif structKeyExists(form, "submitButt")>
    <cfquery datasource="NameOfYourDSN">
      INSERT INTO items(itemDesc) 
      VALUES(
        <cfqueryparam value="#FORM.itemDesc#" cfsqltype="cf_sql_varchar">
      )
    </cfquery>

</cfif>

<!--- 2. After inserting, get new list of items --->
<!--- Avoid SELECT * (select all) and only return the columns you need --->
<cfquery datasource="ESC-ADD-TECH" name="items">
    SELECT *
    FROM items
    ORDER BY itemDesc ASC
</cfquery>

<!--- 3. View Code --->
<html>
<body>
    <div id="myDIV" class="header">
        <h2>My Shopping List</h2>
        <form id="new_item" method="POST" action="nameOfYourScriptHere.cfm">
            <input type="text" name="itemDesc">
            <input name="submitButt" type="submit" class="addBtn">
        </form>
        <cfoutput query="items">  
        <ul>
            <li>#itemsArray#</li>
        </ul>   
        </cfoutput>
    </div>
  </body>
  </html>