2013-06-05 11 views
5

L'app: Una funzione JavaScript è in ascolto per le modifiche sugli elementi del modulo (input & select) e inserisce i dati in un metodo CFC che li assegna a una struttura di sessione. La struttura viene restituita, rendendo i dati del modulo utilizzabili per la durata della sessione. L'app è adattata dal codice allo Raymond Camden's Using a server, or session storage, to persist form values.Sintassi di tag da CFScript a ColdFusion

Edizione: Il codice CFC originale è scritto in CFScript. Perché siamo su ColdFusion 8, ricevo un errore quando viene chiamato il metodo. Quindi, ho tradotto il metodo nella sintassi dei tag ColdFusion e ho smesso di ottenere quell'errore. In Dev Tools di Chrome, posso vedere i dati che passano al CFC tramite l'oggetto JSON ogni volta che inserisco qualcosa in un elemento del modulo. Quindi so che la funzione JavaScript sta funzionando. E anche se non ricevo errori di ritorno, ci sono alcuni comportamenti che mi portano a credere che la mia traduzione non sia corretta. Ad esempio, il dump della struttura della sessione mostra solo l'ultimo elemento di input inserito, piuttosto che tutti (come nel caso della demo di Ray).

Ecco la versione CFScript originale e quindi la mia traduzione di tag. Oltre ai commenti su dove la mia traduzione è sbagliata, mi piacerebbe avere una spiegazione di questa linea, <cfset s.name = [s[name]] />, in particolare il costrutto [s[name]], dal momento che non sono in grado di articolare ciò che sta accadendo lì. Grazie.

sintassi dello script: sintassi

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:

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

risposta

5

Prima di tutto, non è necessario tradurre tutto ciò. CF8 non supporta componente/funzione nel cfscript ma per il resto si è pronti per usarlo come è:

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

Prova semplicemente riconfezionamento il coraggio come questo piuttosto che riscrivere e vedere se si ottiene più lontano.

Per spiegare la notazione in generale: I s[name] indirizzi la struttura di s dalla chiave del valore memorizzato in name; questo è talvolta chiamato notazione array. È equivalente alla notazione punto di s.theValueStoredInName in cui è noto il nome. Per indirizzare dinamicamente una struttura con un nome di variabile, è più semplice farlo tramite notazione di matrice.

Stessa cosa per il set nidificato: La linea s[name] = [s[name]] è l'impostazione di una chiave con un valore di ciò che è memorizzato nel name al valore di ciò che è memorizzato nella chiave denominata di s[name]. Racchiudendo quell'insieme in [], è come un tipo di matrice.

Questo vi aiuterà a chiarire ciò che sta accadendo qui in particolare:

Se qualcosa con quel nome-chiave non è già stato assegnato come una struct, esso viene memorizzato come struct (nome semplice-chiave valore). In caso affermativo, il valore della chiave del nome viene convertito in un array con quella chiave del nome. Quindi se si tratta di un passaggio successivo di un secondo elemento (che sarà, il se! Sta solo controllando se questa conversione di matrice si è già verificata almeno una volta), quindi il secondo elemento viene aggiunto a quell'array che ha la chiave di lo stesso nome

Personalmente, vorrei sempre impostare direttamente un array per semplicità. Quindi sai sempre come indirizzare i valori in memoria.

+0

+1 per menzionare il wrapping anziché la riscrittura – Leigh

+0

Una cosa che devi fare in CF8 se ricordo è spostare i tuoi var nella parte superiore del blocco di script. Altrimenti, cfscript dovrebbe supportare tutte le notazioni moderne dell'oggetto così come sono. CF9 ti consente di var ovunque, come evidentemente ora si verifica il sollevamento in CF9 +. Lo modificherò per riflettere questo. – williambq

+1

@ williambq - Potrebbe essere meglio aggiungere l'ultima parte come [modifica] (http://stackoverflow.com/posts/16948078/edit), quindi è più visibile. Quindi elimina il commento. – Leigh

2

<cfset s.name = ... />

È necessario per accedere ai nomi dei tasti Dyna mically. Il codice sopra riportato utilizza sempre la stessa chiave statica (ad es. name). Quindi finisci per sovrascrivere il valore precedente ogni volta che fai un loop. Questo è il motivo per cui si finisce con un solo valore - l'ultimo.

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

per risolvere il problema, ovunque si utilizza s.name, sostituirlo con s[name]. Inoltre, non dimenticare lo scope var di tutte le variabili locali della funzione.

Aggiornamento:

williambq's response solleva anche un buon punto. Non è necessario convertirlo tutto in cfml. È più semplice racchiuderne la maggior parte nei tag cfscript.

Problemi correlati