2013-06-05 12 views
5

app: JavaScript関数はフォーム要素(入力& select)の変更をリッスンし、それらをセッション構造体に割り当てるCFCメソッドにデータをポストします。構造体が返され、フォームデータをセッションの有効期間中使用可能にします。アプリはRaymond Camden's Using a server, or session storage, to persist form valuesのコードから適合しています。CFScriptからColdFusionタグ構文へのセッションの変換

問題:オリジナルのCFCコードはCFScriptで書かれています。 ColdFusion 8を使用しているため、メソッドが呼び出されるとエラーが発生します。そこで、メソッドをColdFusionのタグ構文に変換して、そのエラーを取り止めました。 Chromeのデベロッパーツールでは、フォーム要素に何かを入力するたびに、JSONオブジェクトを介してCFCに渡すデータを確認できます。だから私はJavaScript関数が動作していることを知っています。また、私は返品エラーがないのに、私の翻訳が間違っていると私に信じさせるいくつかの行動があります。たとえば、セッション構造体のダンプには、入力された最後の入力要素のみが表示されます(Rayのデモの場合のように)。

元のCFScriptのバージョンがあり、次にタグの翻訳があります。私の翻訳が間違っている箇所についてのコメントに加えて、私はこの行の説明を<cfset s.name = [s[name]] />、とりわけ[s[name]]の構成にしたいと思っています。何が起こっているのかを明確にすることができないからです。ありがとう。

スクリプトの構文:

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

タグ構文:

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

答えて

5

まず、すべてを翻訳する必要はありません。 CF8は、CFScriptでのコンポーネント/機能をサポートしていませんが、そうでない場合であるとして、あなたはそれを使用して良いです:

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

は、単純に次のように勇気をリラップではなく、書き換えてみて、あなたが遠く得るかどうかを確認します。

一般的に説明すると: s[name]nameに格納されている値のキーでsの構造を扱います。これは配列記法とも呼ばれます。 名前がわかっているs.theValueStoredInNameのドット表記に相当します。 構造体を変数名で動的に扱うには、配列表記法を使用してこれを行うのが最も簡単です。ネストされたセットのための

同じこと: ラインs[name] = [s[name]]s[name]の名前のキーに格納されているものの値にnameに格納されているものの値を持つキーを設定しています。 []で設定した値をラップすると、配列の型として扱われます。

その名前をキーと何かがすでに構造体として割り当てられていない場合、それは構造体(単純な名前キー値)として保存されます:

これは、特に、ここで何が起こっているかを明確にするのに役立ちます。 これがあれば、name-key値にあるものは、そのname-keyを持つ配列に変換されます。 次に、2番目の項目が連続している場合(この配列変換が既に少なくとも1回は発生しているかどうかをチェックするだけです)、2番目の項目がその配列に追加されます。同じ名前。

個人的には、私は簡単にするために、常に直接配列に設定します。次に、ストレージ内の値をどのように扱うかを常に知っています。

+0

書き換えとは対照的にラッピングに言及してください。 – Leigh

+0

私が思い出したようにCF8で行う必要があることは、あなたのvarをスクリプトブロックの先頭に移動することです。しかし、それ以外の場合は、cfscriptはすべての現代のオブジェクト記法をそのままサポートする必要があります。 CF9では、ホイストが明らかに現時点でCF9 +で発生するため、どこでもvarを使用できます。私はこれを反映するように編集します。 – williambq

+1

@ williambq - 最後の部分を[編集](http://stackoverflow.com/posts/16948078/edit)として追加する方が良いかもしれないので、もっと目に見えます。次に、コメントを削除します。 – Leigh

2

<cfset s.name = ... />

あなたは、キー名にアクセスする必要があるDYNA mically。上記のコードは毎回同じ静的キー(つまりname)を使用しています。したがって、ループするたびに前の値を上書きしてしまいます。だからこそ、あなたは一つの価値、つまり最後の価値のみで終わるのです。

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

あなたがs.nameを使用している、どこでも、それを修正s[name]と交換します。また、varスコープのすべての関数のローカル変数を忘れないでください。

更新:

williambq's responseも良い点を提起します。すべてをcfmlに変換する必要はありません。 cfscriptタグにその大部分を包み込む方が簡単です。

関連する問題