Как использовать тег cfwddx в ColdFusion

Я хотел бы отправить структуру ColdFusion в Javascript. Посмотрев, как я могу это сделать, я обнаружил тег cfwddx. Похоже, что я получил часть пути туда. Я создал тестовую программу

<head>
<script type = "text/javascript" src = "frag3.js"> </script>
</head>
<body>

<cfset str = StructNew()>
<cfset str['betty'] = 1>
<cfset str['nancy'] = 2>
<cfdump var = "#str#">

<cfwddx action="CFML2JS"
    input="#str#"
    toplevelvariable="xyz"
    output = "genstr">

<cfoutput>
<script type = "text/Javascript">
test('betty')
function test (arg) {
alert("got to test");
#genstr#
alert ("xyz " + xyz[arg]);
}
nothing()
</script> 
</cfoutput>

Cfdump дает правильный ответ

вывод cfdump

Когда я смотрю на вывод #genstr#, он содержит правильный код JavaScript:

xyz = new Object(); xyz["betty"] = "1"; xyz["nancy"] = "2"; 

Когда я запускаю код, как показано выше, предупреждение дает правильный ответ. И когда я вызываю функцию "nothing()", которая находится на frag3.js, предупреждение показывает, что она работает, поэтому оператор src работает.

Однако когда я перемещаю сам тест функции (arg) в frag3.js, он не запускается.

Может кто-нибудь сказать мне, как заставить "тестировать" работу как внешнюю функцию, а не просто встроенную в мой код ColdFusion? Кстати, я не изучил JQuery, поэтому ответы JQuery не очень поможет; Мне нужен базовый JavaScript.

3 ответа

Вместо того, чтобы записывать биты переменных (назовем их "инициализация" или "конфигурация") в исходный код вашего веб-сайта (или, что еще хуже, в исходный код ваших статических файлов JS), я рекомендую следующее.

Создайте компонент, имеющий метод удаленного вызова, который возвращает структуру со всей конфигурацией. Теперь вы можете вызвать этот метод из кода ColdFusion на сервере (где вы получите структуру) и через Ajax из кода JavaScript на клиенте (где вы получите JSON).

/** Config.cfc (or call it something similar)
  *
  */

component { 
    remote struct function getConfig() returnformat="JSON" {
        var str = StructNew();
        str['betty'] = 1;
        str['nancy'] = 2;
        return str;
    } 
}

ваш main.cfm (для простоты примера я включаю jQuery для обработки запроса Ajax):

<html>
<head>
  <script type="text/javascript" src="frag3.js"></script>
  <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
  <h1>Config, as seen by the server</h1>
  <cfinvoke component="Config" method="getConfig" returnvariable="cfg">
  <cfdump var="#cfg#">

  <h1>Config, as seen by the client</h1>
  <pre id="cfgDump"></pre>

  <script type="text/javascript">
  $(function () {
      $.get("Config.cfc?method=getConfig").done(function (cfg) {
          // cfg already is a regular JS object at this point
          // convert to JSON again for display purposes
          $("#cfgDump").text( JSON.serialize(cfg, null, 2) );
      });
  });
  </script>
</body>
</html>

Чисто и просто.

Возможно, наиболее эффективным решением вашей проблемы будет включение встроенного динамического содержимого в сам документ.

Когда вы копируете функцию test(arg) в файл Javascript, я полагаю, вы копируете #genstr# также? Так выглядит в файле js именно так, как у вас есть выше?

Это работает как задумано. Файлы.js не обрабатывают Cold Fusion, и если вы посмотрите на консоль разработчика, вы, вероятно, получите синтаксическую ошибку.

Вы можете сохранить его в документе или изменить расширение файла js на.cfm.

На данный момент ваш js_main.cfm (пример) файл будет обрабатываться так же, как и любой другой файл, запрашиваемый браузером, и он будет сбрасывать верхние и нижние колонтитулы, если ваша обработка запросов делает это, поэтому это вызовет больше ошибок. Вы должны защитить эти файлы от этого. Вы можете сделать это с помощью некоторых файлов cfif в вашем приложении, например:

<!--- This checks the path to make sure it doesn't contain livemedia. --->
<cfif not listfind(cgi.script_name,"livemedia","/")>
  ... do includes
</cfif>

Или вы можете сделать так, как я бы, вероятно, сделал, и заблокировать эти файлы в папке только для обслуживания JS, CSS-файлов с расширением cfm с их собственным application.cfc/cfm для переопределения глобального файла сайта, если я столкнулся с ситуацией, в которой я чувствовал что динамически генерируемый js/css был действительно лучшим вариантом.

Затем вы можете делать то, что показываете в своем OP, и передавать переменные на клиентскую сторону, если вам действительно это нужно. В качестве альтернативы, вы можете называть два "приложения" одинаковыми, и хотя это делает обмен данными действительно простым, я все же должен посоветовать вам быть осторожным с тем, что вы делитесь, и вы раскрываете и проверяете правильность защиты субприложения.

И да, как и предполагали другие, #SerializeJSON()# Это современный подход к копированию серверной переменной / объекта на стороне клиента.

Например..

<cfset CFStruct = {big = "little", red = "blue", subArray = ["A","B","C","D"]} />
<script>
  <cfoutput>JSObj = #SerializeJSON(CFStruct)#;</cfoutput>
</script>
<!--- While I use shorthand to form the struct and subArray, that's only for speed,
  structs, arrays, queries, etc formed in any fashion work just fine. --->

Создает JSObj с элементами big, red, subArray (который имеет дочерние элементы A, B, C, D).

Все равно, какой бы метод вы ни выбрали (wddx или же SerializeJSON()), они не будут работать в файле.js.

Я должен упомянуть, что есть другой вариант, позволяющий серверу анализировать файлы.js, но это будет намного более болезненным, чем оно того стоит. Во многих случаях, когда вы будете использовать простой js-файл, будут возникать помехи.

Обратите внимание, что ваши файлы вызываются через теги на стороне клиента <script> а также <link> полностью отдельные запросы. Они не будут делиться url, form, request, variables прицелы. Однако они могут поделиться cookies а также client а также session область действия, если два приложения имеют одинаковое имя.

Наконец, замечательная вещь о внешнем контенте, называемом через HTML-теги, независимо от расширения, заключается в том, что он обычно кэшируется по умолчанию. Это замечательно для пропускной способности и даже для быстрой загрузки страниц, пока у вас не будет сценария, когда вы хотите последовательно загружать не кэшированные копии.

По этой причине, когда вы чувствуете, что должны динамически генерировать что-то, что вы хотите вставить во внешний файл, у вас есть несколько методов.

  1. Вы можете установить no-cache в заголовке (CF или Htaccess могут сделать это).
  2. Вы можете указать случайное число в строке запроса вызова скрипта. <script src="/livemedia/js_main.cfm?randomizer=#randrange(1,1000000)#"></script>
  3. Возможно, файл не нужно обновлять каждый раз для каждого пользователя, может быть, просто каждый пользователь должен видеть свою копию. Вы все равно прикрепите строку запроса, потому что несколько пользователей могут войти в систему с одного компьютера. Это, однако, будет зависеть от пользователя. <script src="/livemedia/js_main.cfm?#session.username#"></script>
  4. Пересмотрите, как ваша страница компилирует и хранит данные, которые должны быть встроены в страницу.

Если вы присоединяете что-то к строке запроса файла javascript, вам следует переместить статическое содержимое файла в отдельный файл, который не нужно каждый раз восстанавливать. Нет необходимости перезагружать 15 функций JavaScript с каждым запросом страницы, потому что 1 содержит динамическое содержимое.

Я не большой разработчик CF, но самый простой способ, которым я знаю, для вывода структур и массивов для использования javascript - это использование JSON SerializeJson()

Например, как переменная JS на странице CF:

<script>
    var myVar = <cfoutput>#SerializeJson(str)#</cfoutput>;
</script>

Хотя JSON является строкой... когда он печатается внутри тега script, javascript будет читать его как массив или объект без необходимости синтаксического анализа в клиенте.

Я использую точно такой же вывод для доставки AJAX также

Другие вопросы по тегам