2013-06-05 22 views
5

Ứng dụng: Chức năng JavaScript lắng nghe các thay đổi trên phần tử biểu mẫu (nhập & chọn) và đăng dữ liệu lên phương pháp CFC gán chúng cho cấu trúc Phiên. Cấu trúc được trả về, làm cho dữ liệu biểu mẫu có thể sử dụng được trong suốt thời gian của phiên. Ứng dụng được điều chỉnh từ mã số tại Raymond Camden's Using a server, or session storage, to persist form values.Phiên dịch từ CFScript sang cú pháp thẻ ColdFusion

Vấn đề: Mã CFC gốc được viết bằng CFScript. Bởi vì chúng tôi đang ở trên ColdFusion 8, tôi gặp lỗi khi phương thức được gọi. Vì vậy, tôi dịch các phương pháp thành cú pháp thẻ Coldfusion và ngừng nhận được lỗi đó. Trong Công cụ tìm kiếm của Chrome, tôi có thể xem dữ liệu chuyển đến CFC qua đối tượng JSON mỗi khi tôi nhập nội dung nào đó vào phần tử biểu mẫu. Vì vậy, tôi biết chức năng JavaScript đang hoạt động. Và mặc dù tôi không nhận được bất kỳ lỗi trả lại nào, nhưng có một số hành vi khiến tôi tin rằng bản dịch của tôi không chính xác. Ví dụ: kết xuất của cấu trúc phiên chỉ hiển thị phần tử đầu vào cuối cùng được nhập, thay vì tất cả chúng (như trường hợp trong bản trình diễn của Ray).

Đây là phiên bản CFScript gốc và sau đó là bản dịch thẻ của tôi. Ngoài bất kỳ nhận xét nào về bản dịch của tôi là sai, tôi muốn có một giải thích về dòng này, <cfset s.name = [s[name]] />, đặc biệt là cấu trúc [s[name]] vì tôi không thể nói rõ những gì đang xảy ra ở đó. Cảm ơn.

kịch bản cú pháp:

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;  
    } 
} 

tag cú pháp:

<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> 

Trả lời

5

Trước hết, bạn không thực sự cần dịch tất cả điều đó. CF8 không hỗ trợ phần/chức năng trong cfscript nhưng nếu không bạn rất tốt để sử dụng nó như là:

<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> 

Hãy thử đơn giản là xuống dòng tự động can đảm như thế này chứ không phải viết lại và xem nếu bạn nhận được xa hơn.

Để giải thích ký hiệu nói chung: s[name] địa chỉ cấu trúc của s bằng khóa của giá trị được lưu trữ trong name; điều này đôi khi được gọi là ký hiệu mảng. Nó tương đương với ký hiệu dấu chấm của s.theValueStoredInName nơi tên được biết. Để giải quyết cấu trúc theo tên biến động, cách dễ nhất là thực hiện điều này thông qua ký hiệu mảng.

điều tương tự cho bộ lồng nhau: Dòng s[name] = [s[name]] là thiết lập một phím với giá trị của những gì được lưu trữ trong name với giá trị của những gì được lưu trữ trong các khóa có tên của s[name]. Bằng cách đóng gói được đặt trong [], nó là một loại mảng.

Điều này sẽ giúp làm rõ những gì đang xảy ra ở đây cụ thể là:

Nếu một cái gì đó với tên-key đã chưa được chỉ định là một cấu trúc, nó được lưu trữ như là một struct (giá trị tên-key đơn giản). Nếu có, thì giá trị khóa-tên sẽ được chuyển thành một mảng với tên khóa đó. Sau đó, nếu nó là một vượt qua liên tiếp của một mục thứ 2 (mà nó sẽ được, nếu! Chỉ kiểm tra nếu chuyển đổi mảng này đã xảy ra ít nhất một lần), sau đó mục thứ 2 được nối vào mảng đó có khóa cùng tên.

Cá nhân, tôi sẽ luôn đặt trực tiếp vào một mảng để đơn giản. Sau đó, bạn luôn biết cách xử lý các giá trị trong bộ nhớ.

+0

+1 để đề cập đến gói như trái ngược với viết lại – Leigh

+0

Một điều bạn cần làm trong CF8 nếu tôi nhớ lại là di chuyển var của bạn lên đầu khối tập lệnh. Nhưng nếu không thì cfscript sẽ hỗ trợ tất cả các ký hiệu đối tượng hiện đại như vậy. CF9 cho phép bạn var bất cứ nơi nào như cẩu hiện rõ ràng bây giờ xảy ra trong CF9 +. Tôi sẽ chỉnh sửa điều đó để phản ánh điều này. – williambq

+1

@ williambq - Có thể tốt hơn để thêm phần cuối cùng đó dưới dạng [sửa] (http://stackoverflow.com/posts/16948078/edit), vì vậy nó hiển thị rõ hơn. Sau đó xóa nhận xét. – Leigh

2

<cfset s.name = ... />

Bạn cần truy cập vào tên chính Dyna mically. Mã trên sử dụng cùng một khóa tĩnh (tức là name) mỗi lần. Vì vậy, bạn sẽ ghi đè lên giá trị trước đó mỗi khi bạn lặp lại. Đó là lý do tại sao bạn kết thúc chỉ với một giá trị - giá trị cuối cùng.

<!--- 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 = "..." /> 

Để khắc phục nó, ở khắp mọi nơi bạn đang sử dụng s.name, thay thế nó với s[name]. Ngoài ra, đừng quên var phạm vi tất cả các biến địa phương của hàm của bạn.

Cập nhật:

williambq's response cũng làm dấy lên một điểm tốt. Bạn không phải chuyển đổi tất cả thành cfml. Nó đơn giản hơn để bọc số lượng lớn của nó trong các thẻ cfscript.

Các vấn đề liên quan