Отправка JSON в javascript на GSP

Я использую Grails 2.3.7, и у меня есть действие контроллера следующим образом:

def testData(){
    def result = [:]
    result['name'] = "Sales"
    result['type'] = "bar"
    result['data'] = [5, 20, 45, 10, 10, 20]
    [data: result as JSON]
}

В testData.gsp я хотел бы получить объект JSON в javascript:

<script>
    $(document).ready(function(){
        var data = JSON.parse(${data});
    })
</script>

Затем я получил исключение:

Uncaught SyntaxError: Unexpected token {

в строке:

var data = JSON.parse({&quot;name&quot;:&quot;Sales&quot;,&quot;type&quot;:&quot;bar&quot;,&quot;data&quot;:[5,20,45,10,10,20]});

Похоже, что JSON испорчен. Я думаю, что он работал так. Может, это новый Grails? Как я могу это исправить? Спасибо.

Update: Задача решена. См. Комментарии в принятом ответе.

Update2: Когда я проверю приложение сегодня, он снова не сработал. Я сделал то, что требовалось документам с "сырым" методом, но не повезло. Обходным путем является использование "Per Page Encoding". Это я тщательно проверил. Он работает.

Ответы

Ответ 1

Проблема заключается в том, что JSON кодируется как HTML. Вместо этого попробуйте следующее:

контроллер

def testData() {
    def result = [:]
    result['name'] = "Sales"
    result['type'] = "bar"
    result['data'] = [5, 20, 45, 10, 10, 20]
    [data: result as JSON]
}

GSP

<script>
    var data = ${raw(data)};
</script>

Вам не нужно $(document).ready, потому что код JS

var data = ${raw(data)};

создается на стороне сервера

Ответ 2

Метод encodeAsJSON() хорошо работает для вывода данных JSON в JavaScript:

контроллер

def testData() {
   def data = [name: "Sales", values: [5, 20, 45]]
   [data: data]
   }

Просмотр (GSP)

<script>
var data1 = ${raw(data)};  //{name=Sales, values=[5, 20, 45]}
var data2 = ${raw(data as grails.converters.JSON)};  //{&quot;name&quot;:&quot;Sales...
var data3 = ${data.encodeAsJSON()};  //{"name":"Sales","values":[5,20,45]}  CORRECT!
</script>

Использование raw() в объекте Groovy не создает выход, совместимый с JavaScript (см. data1), и его использование после преобразования JSON приводит к нежелательной кодировке &quot; (см. data2). Использование encodeAsJSON() создает правильный вывод (см. data3).

Документация:
  http://grails.org/doc/latest/guide/security.html#codecs

Update:
Я перешел на использование taglib с помощью:

out << "<script>var data = " + raw((data as JSON) as String) + ";</script>"

Ответ 3

Работа решение:

def action() {
  [data: data as JSON]
}

Страница GSP:

<g:applyCodec encodeAs="none">
    var data = ${data};
</g:applyCodec>

Ответ 4

В testData.gsp add

<%@page expressionCodec="none" %>

и в script

<script>
   $(document).ready(function(){
    var data = ${data};
})
</script>

Ответ 5

Следующее работало для меня с использованием Grails 2.4.3:

Контроллер:

def result = [:]
result['type'] = "bar"
result['data'] = [5, 20, 45]

model: [data: result as JSON]

GSP:

<script>
// this worked!
var data = ${raw(data as String)};
</script>

Произведен желаемый результат:

<script>
// this worked!
var data = {"type":"bar","data":[5,20,45]};
</script>

Принятый ответ Dónal DID НЕ работает для меня:

Контроллер (тот же, что и мой рабочий пример выше)

GSP (не работал):

<script>
// did NOT work!!
var data = ${raw(data)};
</script>

Произведен такой же плохой результат:

<script>
// did NOT work!!
var data = {&quot;type&quot;:&quot;bar&quot;,&quot;data&quot;:[5,20,45]};
</script>

Ответ 6

Это работало для меня в grails 3.1.9.

Контроллер:

def result = [:]
result['type'] = "bar"
result['data'] = [5,20,45]
result['key'] = token

[data:result as JSON]

GSP:

<script>

var data = '${raw(data as String)}';
var json = JSON.parse(data);
alert(json.type);

var authorization = json.key;

</script>

Ответ 7

Не все версии grails поддерживают метод raw() или g: applyCodec taglib.

Решение состоит в том, чтобы использовать блок <% =% > , чтобы избежать экранирования

<%= users.collect({id:it.id,value:it.name}) as grails.converters.JSON%>

Ответ 8

Это также может помочь, передавая данные как простую модель и анализируя ее как JSON в gsp.

def testData() {
    def result = [:]
    ...
    [data: result]
}

В представлении

<%! import grails.converters.JSON %>
...
<script>
function parseModelToJS(jsonString)
{
 jsonString=jsonString.replace(/\"/g,'"');
 var jsonObject=$.parseJSON(jsonString);
 return jsonObject
}

$(document).ready(function(){
 var data=parseModelToJS('${data as JSON}');
 console.log(data);
});
</script>

http://www.oodlestechnologies.com/blogs/Parse-model-to-json-on-gsp-in-grails

Ответ 9

Вы можете сделать это,

import groovy.json.*
Map testMap = ['name': 'Test']
String jsonData = new JsonBuilder(testMap).toPrettyString()
render(view: view, model: ["data": jsonData], params: [:])

В вашем gsp:

 <script>
    var data = ${raw(data)};
</script>

Простой..