2013-06-05 2 views
5

Приложение: Функция JavaScript прослушивает изменения в элементах формы (ввод &) и отправляет данные в метод CFC, который назначает их структуре сеанса. Структура возвращается, делая данные формы полезными для жизни сеанса. Приложение адаптировано с кодом на Raymond Camden's Using a server, or session storage, to persist form values.Перевести сеанс с синтаксиса тегов CFScript на ColdFusion

Вопрос: Исходный код CFC написан на CFScript. Поскольку мы находимся в ColdFusion 8, я получаю сообщение об ошибке при вызове метода. Итак, я перевел этот метод в синтаксис тегов ColdFusion и прекратил эту ошибку. В Dev Dev Tools от Chrome я могу видеть данные, передаваемые CFC через объект JSON каждый раз, когда я ввожу что-то в элемент формы. Поэтому я знаю, что функция 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> 

Попробуйте просто rewrapping кишка тонка, как это, а не переписывание и посмотреть, если вы получаете дальше.

Для объяснения обозначений, как правило: The s[name] адреса структура s по ключу значения, хранящегося в name; это иногда называют записью массива. Это эквивалентно точечной нотации s.theValueStoredInName, где имя известно. Чтобы динамически обращаться к структуре по имени переменной, проще всего это сделать с помощью записи массива.

То же самое для вложенного набора: Линии s[name] = [s[name]] устанавливает ключ со значением того, что хранится в name к стоимости того, что хранится в названном ключе s[name]. Посредством упаковки, установленной в [], она является типом массива.

Это поможет прояснить, что происходит здесь, в частности:

Если что-то с этим именем ключом еще не было назначено в качестве структуры, он получает хранятся в виде структуры (простое имя-значение ключа). Если это так, то то, что когда-либо было в значении ключа ключа, преобразуется в массив с этим ключом. Тогда, если это последовательный проход 2-го элемента (каким он будет, if! Просто проверяет, произошло ли это преобразование массива хотя бы один раз), то второй элемент добавляется к этому массиву, который имеет ключ от одно и то же имя.

Лично я бы всегда просто устанавливал массив для простоты. Тогда вы всегда знаете, как обращаться со значениями в хранилище.

+0

+1 для упоминания обертывания в отличие от перезаписи – Leigh

+0

Одна вещь, которую нужно сделать в CF8, если я помню, - это переместить ваш var в верхнюю часть блока сценария. Но в противном случае cfscript должен поддерживать все современные обозначения объектов как есть. CF9 позволяет вам var где-нибудь, поскольку подъем теперь, очевидно, происходит в CF9 +. Я отредактирую это, чтобы отразить это. – williambq

+1

@ williambq - Лучше добавить эту последнюю часть как [edit] (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 всю локальную переменную вашей функции.

Update:

williambq's response также поднимает хороший момент. Вам не нужно преобразовывать все это в cfml. Проще всего обернуть большую часть его в тегах cfscript.

 Смежные вопросы

  • Нет связанных вопросов^_^