简体   繁体   English

传入HTML DOM中的JSON对象

[英]passing in a JSON object in HTML DOM

I am experimenting with a charting package called Highcharts (some of you may be familiar with it but regardless the problem is not related to Highcharts per se). 我正在尝试一个名为Highcharts的图表包(你们中的一些人可能对它很熟悉,但无论问题与Highcharts本身无关)。 What I wanted to do was have my PHP generated HTML embed a JSON object into the DOM which would then be picked up by a static jQuery listening function. 我想要做的是让我的PHP生成的HTML将一个JSON对象嵌入到DOM中,然后由静态jQuery监听功能拾取。 Here's what it looks like: 这是它的样子:

 // Static JS file that get's loaded with every page load and 
 // and listens for a class with ".highchart_config".
 // When it finds a config class it then looks in the attribute "data-chart"
 // for the JSON configuration object
 jQuery.noConflict();
 jQuery(function($) {
   $(document).ready(function() {
    $(".highchart_config").each(function(index) {
        var config_obj = $(this).attr('data-chart');
        chart = new Highcharts.Chart( config_obj );
    });
   });
 }); 

And then the HTML is as follows: 然后HTML如下:

 <div class="highchart_config" data-chart='         {chart: {"renderTo":"chart2","defaultSeriesType":"column"},title: {"text":"Monkies are Happy Animals"},xAxis:{"categories":["Apples","Oranges","Pears","Grapes","Bananas"],"min":null,"title":""},yAxis: {"min":0,"title":{"text":"Total fruit consumption"}},legend: {"align":"center","x":0,"verticalAlign":"bottom","y":0,"floating":false,"backgroundColor":null,"borderColor":"#CCC","borderWidth":1,"shadow":false,"reversed":true},tooltip: { formatter: function() { return this.series.name + ":" + this.y + " "}},plotOptions: {"column":{"stacking":"normal","dataLabels":{"enabled":false}}},series: [{"name":"Running","data":[5,3,4,7,2]},{"name":"Cycling","data":[2,2,3,2,1]},{"name":"Lifting","data":[3,4,4,2,5]}]}'></div>

Using a debugger I can see this working by placing a breakpoint on the line where Highcharts object instantiation takes place. 使用调试器我可以通过在Highcharts对象实例化发生的行上放置断点来看到这一点。 When the breakpoint is hit I print the value of "chart_obj" which comes out as: 当断点被击中时,我打印出“chart_obj”的值,它出现为:

  {chart: {"renderTo":"chart2","defaultSeriesType":"column"},title: {"text":"Monkies are Happy Animals"},xAxis:{"categories":["Apples","Oranges","Pears","Grapes","Bananas"],"min":null,"title":""},yAxis: {"min":0,"title":{"text":"Total fruit consumption"}},legend: {"align":"center","x":0,"verticalAlign":"bottom","y":0,"floating":false,"backgroundColor":null,"borderColor":"#CCC","borderWidth":1,"shadow":false,"reversed":true},tooltip: { formatter: function() { return this.series.name + ":" + this.y + " "}},plotOptions: {"column":{"stacking":"normal","dataLabels":{"enabled":false}}},series: [{"name":"Running","data":[5,3,4,7,2]},{"name":"Cycling","data":[2,2,3,2,1]},{"name":"Lifting","data":[3,4,4,2,5]}]} 

That looks "right" to me but it doesn't work. 这看起来对我来说“正确”,但它不起作用。 Instead the instantiation of the object fails as the config_obj is somehow malformed. 相反,对象的实例化失败,因为config_obj以某种方式格式错误。 To make sure I wasn't making some stupid syntax error I cut and paste the value in config_obj and put it into a static JS file that looks like this: 为了确保我没有做出一些愚蠢的语法错误,我将该值剪切并粘贴到config_obj中并将其放入一个静态JS文件,如下所示:

 $(function () {
    var chart;
    $(document).ready(function() {
        chart = new Highcharts.Chart({
            chart: {"renderTo":"chart2","defaultSeriesType":"column"},title: {"text":"Monkies are Happy Animals"},xAxis: {"categories":["Apples","Oranges","Pears","Grapes","Bananas"],"min":null,"title":""},yAxis: {"min":0,"title":{"text":"Total fruit consumption"}},legend: {"align":"center","x":0,"verticalAlign":"bottom","y":0,"floating":false,"backgroundColor":null,"borderColor":"#CCC","borderWidth":1,"shadow":false,"reversed":true},tooltip: { formatter: function() { return this.series.name + ":" + this.y + " "}},plotOptions: {"column":{"stacking":"normal","dataLabels":{"enabled":false}}},series: [{"name":"Running","data":[5,3,4,7,2]},{"name":"Cycling","data":[2,2,3,2,1]},{"name":"Lifting","data":[3,4,4,2,5]}]
        });
    });
});

This "hardcoded" method works and yet the instantiation call should have precisely the same configuration object passed in. I'm at a loss now how to proceed. 这种“硬编码”方法可行,但实例化调用应该具有完全相同的配置对象传递。我现在不知道如何继续。 I have been reading other posts on stackoverflow around this topic but can't find anything to help me with my specific problem. 我一直在阅读关于此主题的stackoverflow上的其他帖子,但找不到任何可以帮助我解决我的具体问题。 Any and all help is greatly appreciated. 非常感谢任何和所有的帮助。

UPDATE: I have no tried ... to no avail using both data() and attr() methods and in both cases with and without a call to JSON.parse(config_obj). 更新:我没有尝试过...无法使用data()和attr()方法,无论是否调用JSON.parse(config_obj)。 It DOES appear that the problem is related to config_obj being treated as a string so in the debugger I decided to assign a variable "test" to the cut-and-pasted string results of config_obj without the exterior quotation marks. 看来这个问题与config_obj被视为一个字符串有关,因此在调试器中我决定将一个变量“test”分配给config_obj的剪切和粘贴字符串结果,而没有外部引号。 It works fine so it's clearly a well structured JSON string but getting it converted to a string is still eluding me. 它运行正常所以它显然是一个结构良好的JSON字符串,但将它转换为字符串仍然是我的意思。 Below I have an image of my debugging session which shows three things: 下面我有一个调试会话的图像,它显示了三件事:

  1. First I get an error when using the JSON.parse() function on my config_obj string (that's true regardless if I used data() or attr() to retrieve config_obj from the DOM) 首先我在config_obj字符串上使用JSON.parse()函数时出错(无论我是否使用data()或attr()从DOM中检索config_obj,都是如此)
  2. If I instead just cut-and-paste the text into a test variable called "test" it is recognised as a valid JS object 如果我只是将文本剪切并粘贴到名为“test”的测试变量中,则将其识别为有效的JS对象
  3. If I use the JSON.stringify() method on the test object it converts back to a string version that is CLOSE to the same as my config_obj variable ... the difference being that the first level attributes in the object have quotation marks around them. 如果我在测试对象上使用JSON.stringify()方法,它会转换回CLOSE的字符串版本,与我的config_obj变量相同...不同之处在于对象中的第一级属性在它们周围有引号。 This might be a hint at what's going wrong but I still haven't cracked this nut ... any help would be greatly appreciated. 这可能暗示出现了什么问题,但我仍然没有破解这个坚果......任何帮助都会非常感激。

分配给变量然后stringify

When you get the attributes value - using .attr() - what you're being returned is a string. 当你获得属性值 - 使用.attr() - 你返回的是一个字符串。 You'll need to parse that string to turn it into the actual object, so change the following line to: 您需要解析该字符串以将其转换为实际对象,因此请将以下行更改为:

chart = new Highcharts.Chart( JSON.parse(config_obj) );

It's the JSON.parse() function that's the important part. 这是JSON.parse()函数,它是重要的部分。

Also, as a note, if you're using data-* attributes, it's better to use the .data() function, so you'd change the other line to: 另外,作为注释,如果您使用data-*属性,最好使用.data()函数,因此您将另一行更改为:

var config_obj = $(this).data('chart');

As you may have seen in my "update" to the question I had found a variation in the string versions of the JSON object between my original object and the one I created by cut-and-pasting this same string into an object and then running JSON.stringify() on it. 正如您在我对问题的“更新”中看到的那样,我在原始对象和通过将相同的字符串剪切并粘贴到对象中然后运行之间创建的JSON对象的字符串版本中发现了变体。 JSON.stringify()就可以了。

This variation -- including double quote markers around object names -- seems to be important for it to work correctly. 这种变化 - 包括对象名称周围的双引号标记 - 似乎对它正常工作很重要。 If you pass it in this way using jQuery's .data() method than it automatically converts it to a JSON object and there's no need to directly call JSON.parse(). 如果你使用jQuery的.data()方法以这种方式传递它,而不是自动将它转换为JSON对象,并且不需要直接调用JSON.parse()。

I still find it odd that there is a stricter standard to convert a string to an object with JSON's parse() method than there is within JS itself and I'd be interested if anyone has any theories on this. 我仍然觉得奇怪的是,有一个更严格的标准,用JSON的parse()方法将字符串转换为对象,而不是JS本身,如果有人对此有任何理论,我会感兴趣。 In either event, wanted to thank @Anthony, @DCoder and everyone else who helped. 在任何一种情况下,都要感谢@Anthony,@ DCoder和其他帮助过的人。

Here is the working DOM entry: 这是工作DOM条目:

<div class="highchart_config" data-chart='{"chart":{"renderTo":"chart2","defaultSeriesType":"column"},"title":{"text":"Monkies are Happy Animals"},"xAxis":{"categories":["Apples","Oranges","Pears","Grapes","Bananas"],"min":null,"title":""},"yAxis":{"min":0,"title":{"text":"Total fruit consumption"}},"legend":{"align":"center","x":0,"verticalAlign":"bottom","y":0,"floating":false,"backgroundColor":null,"borderColor":"#CCC","borderWidth":1,"shadow":false,"reversed":true},"tooltip":{},"plotOptions":{"column":{"stacking":"normal","dataLabels":{"enabled":false}}},"series":[{"name":"Running","data":[5,3,4,7,2]},{"name":"Cycling","data":[2,2,3,2,1]},{"name":"Lifting","data":[3,4,4,2,5]}]}'></div> 

And the JS that takes this DOM entry as input is: 将DOM条目作为输入的JS是:

jQuery.noConflict();
jQuery(function($) {
  $(document).ready(function() {
    $(".highchart_config").each(function(index) {
        var config_obj = $(this).data('chart');
        chart = new Highcharts.Chart( config_obj );
    });
  });
}); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM