使用AngularJS中的重复键迭代json响应[重复]

Posted

技术标签:

【中文标题】使用AngularJS中的重复键迭代json响应[重复]【英文标题】:Iterating over json response with duplicate keys in AngularJS [duplicate] 【发布时间】:2018-11-12 11:36:09 【问题描述】:

我一直在尝试从我的 Angular 应用程序中的 API 调用中获取响应 json 数据的一部分。

我尝试了各种组合,但我只能获取最后一条记录,而不是两条记录。

这是我的html

<div ng-controller="MyCtrl">
<li ng-repeat="x in textvalues">
        x.event.description 
</li>
</div>

和控制器代码

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $http) 

    $http.get('http://www.vizgr.org/historical-events/search.php?', params: format: 'json', query:'India', limit:'2').then(function(response) 
            $scope.textvalues = response.data;
            console.log($scope.textvalues);
        );


API调用的响应如下:


  "result": 
    "count": "2",
    "event": 
      "date": "-293",
      "description": "When an invasion of",
      "lang": "en",
      "category1": "By place",
      "category2": "Persia",
      "granularity": "year"
    ,
    "event": 
      "date": "-250",
      "description": "The Mauryan s",
      "lang": "en",
      "category1": "By place",
      "category2": "India",
      "granularity": "year"
    
  

我正在尝试在 UI 上循环打印事件描述

这是我的小提琴 - http://jsfiddle.net/nirajupadhyay/Jd2Hw/105/

我尝试了响应数据的各种组合,但无法同时获得两种描述。

请帮忙。

【问题讨论】:

您能否提供 API vizgr.org/historical-events/search.php 的代码,您将在其中创建要返回的最终对象。 @NanditaAroraSharma 这是一个免费提供的公共 API - 这里是 vizgr.org/historical-events 【参考方案1】:

由于 Nandita Arora Sharma 回答 API 响应错误。

RFC-7159,由 (IETF) 发布的 JSON 标准,声明:

" 4. 对象

...单个冒号在每个名称之后,分隔名称 从价值。单个逗号将值与以下值分开 姓名。对象中的名称应该是唯一的。”

使用 Postman 进行 API 测试。如前所述,它呈现 JSON,并且只有一个事件。这可能是angular只能重复1次的原因

原始数据中的所有事件对象都具有重复的键。

【讨论】:

【参考方案2】:

我觉得这个 API 在某种程度上是错误的。 JSON 对象永远不能有 2 个相同的键,其中有不同的值。如果您检查网络选项卡,那么您将看到响应在对象中只有 1 个事件键,其值是对象返回的最后一个值。因此,虽然它可能会在字符串化版本中显示 2 个事件,但它永远不会为 JSON 对象中的同一键保存 2 个值。

阅读Does JSON syntax allow duplicate keys in an object?

不要将 format: json 传递给 API,而是不要传递任何 format 参数。它将以 xml 格式给出结果。然后通过一些库或代码将这个xml格式转换为json格式,如下所示。

var myApp = angular.module('myApp', []);

function MyCtrl($scope, $http) 

  $http.get('http://www.vizgr.org/historical-events/search.php?', 
    params: 
      /* format: 'json', */
      query: 'India',
      limit: '2'
    
  ).then(function(response) 
    console.log(response.data);
    var dom = parseXml(response.data);
    var json = xml2json(dom)
    console.log(json)
    $scope.events = json.result.event;
  );

  function parseXml(xml) 
   var dom = null;
   if (window.DOMParser) 
      try  
         dom = (new DOMParser()).parseFromString(xml, "text/xml"); 
       
      catch (e)  dom = null; 
   
   else if (window.ActiveXObject) 
      try 
         dom = new ActiveXObject('Microsoft.XMLDOM');
         dom.async = false;
         if (!dom.loadXML(xml)) // parse error ..

            window.alert(dom.parseError.reason + dom.parseError.srcText);
       
      catch (e)  dom = null; 
   
   else
      alert("cannot parse xml string!");
   return dom;


function xml2json(xml) 
  try 
    var obj = ;
    if (xml.children.length > 0) 
      for (var i = 0; i < xml.children.length; i++) 
        var item = xml.children.item(i);
        var nodeName = item.nodeName;

        if (typeof (obj[nodeName]) == "undefined") 
          obj[nodeName] = xml2json(item);
         else 
          if (typeof (obj[nodeName].push) == "undefined") 
            var old = obj[nodeName];

            obj[nodeName] = [];
            obj[nodeName].push(old);
          
          obj[nodeName].push(xml2json(item));
        
      
     else 
      obj = xml.textContent;
    
    return obj;
   catch (e) 
      console.log(e.message);
  


在这里查看 js fiddle。

【讨论】:

使用原生 javascript 的好答案。 jQuery 库可用于简化从 XML 中提取数据的任务。【参考方案3】:

你所指的object结构can never exist


  "result": 
    "count": "2",
    "event": 
      "date": "-293",
      "description": "When an invasion of",
      "lang": "en",
      "category1": "By place",
      "category2": "Persia",
      "granularity": "year"
    ,
    "event": 
      "date": "-250",
      "description": "The Mauryan s",
      "lang": "en",
      "category1": "By place",
      "category2": "India",
      "granularity": "year"
    
  

如果在对象中重复了任何key,它将覆盖 JSON 对象 key value pair 中先前设置的 value。 API 应该返回的内容应该如下所示,那么只有您可以获取所有事件对象。


  "result": 
    "count": "3",
    "event": [
      "date": "-250",
      "description": "The Mauryan ''Lion Capital of Asoka'', is erected as part of a pillar at Sarnath, Uttar Pradesh in India (approximate date). It is now preserved at the Sarnath Museum in Sarnath.",
      "lang": "en",
      "category1": "By place",
      "category2": "India",
      "granularity": "year"
    ,
    
      "date": "-250",
      "description": "The Mauryan ''Lion Capital of Asoka'', is erected as part of a pillar at Sarnath, Uttar Pradesh in India (approximate date). It is now preserved at the Sarnath Museum in Sarnath.",
      "lang": "en",
      "category1": "By place",
      "category2": "India",
      "granularity": "year"
    ,
    
      "date": "-250",
      "description": "The Mauryan ''Lion Capital of Asoka'', is erected as part of a pillar at Sarnath, Uttar Pradesh in India (approximate date). It is now preserved at the Sarnath Museum in Sarnath.",
      "lang": "en",
      "category1": "By place",
      "category2": "India",
      "granularity": "year"
    ]
  

【讨论】:

这里是 API - vizgr.org/historical-events 我觉得这个 API 在某种程度上是错误的。 JSON 对象永远不能有 2 个相同的键,其中有不同的值。如果您检查网络选项卡,那么您将看到响应在对象中只有 1 个事件键,其值是对象返回的最后一个值。因此,虽然它可能会在字符串化版本中显示 2 个事件,但它永远不会为 JSON 对象中的同一键保存 2 个值。 阅读此***.com/questions/21832701/… @Niraj 我添加了另一个答案。请看一下。这不能通过你的方式来实现,因为这个公共 API 对我来说似乎有问题!【参考方案4】:

您需要将 $http 作为参数传递给您的控制器,您可以在控制器中看到特定错误为 "$http is not defined"

function MyCtrl($scope,$http) 

WORKING FIDDLE

为了回答您的实际问题,您的服务返回一个对象而不是数组。 iT 返回一个对象对象。所以在这种情况下你不能使用 ng-repeat 。它返回

"result":"count":"3","event":"date":"-250","description":"The Mauryan ''阿育王的狮子资本'',作为支柱的一部分竖立在 印度北方邦的鹿野苑(大约日期)。就是现在 保存在鹿野苑博物馆 Sarnath.","lang":"en","category1":"作者 place","category2":"India","granularity":"year"

为了访问事件,您可以使用

   textvalues.result.event.description

DEMO

【讨论】:

谢谢@sajeetharan 我更正了错字。但问题仍然存在。有两个事件描述,我希望能够打印两个 检查更新的答案 再次感谢 Sajeetharan。因此,这只会在 UI 上打印其中一个事件描述。如果您查看开发人员工具 -> 网络 -> 响应,则有 3 个事件对象。我正在尝试获取所有这些并将它们显示为我的 UI 上的列表 这很奇怪,因为即使它在代码中显示了 3 个对象,它也只有 1 个。让我检查一下

以上是关于使用AngularJS中的重复键迭代json响应[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何迭代由json对象中的键访问的数组[重复]

如何在 AngularJS 中使用 ng-repeat 迭代键和值?

使用动态键检索 JSON 响应数据 [重复]

使用 AngularJS 从 JSON 响应中获取图像 url

从服务器端nodejs到angularjs的有限json响应

AngularJS 表单。 JSON中的可选属性[重复]