JSON @attributes和@association级别在js和/或angularjs中的应用

17

我目前正在进行一个项目,使用 API 检索、更新和删除数据。我使用的 API 是 prestashop API。所以在能够检索数据和更新一些项目后,我遇到了一个问题。根据文档中所说,通过 API 发送和检索的所有数据都是使用 jsonxml。由于 API 的某些数据在 json 返回中具有不同级别,如 @attributes 和 @associations 级别,因此我想问这个问题。

问题是,我想访问这些数据,并与 angularjs 结合使用来显示这些数据。让我给您展示一个我试图实现的快速示例。

首先,JSON 返回将是这样的。

{"products":{"product":[{"id":"1","id_manufacturer":"1","id_supplier":"1","id_category_default":"5","new":{},"cache_default_attribute":"1","id_default_image":"1","id_default_combination":"1","id_tax_rules_group":"1","position_in_category":"0","manufacturer_name":"Fashion Manufacturer","quantity":"0","type":"simple","id_shop_default":"1","reference":"demo_1","supplier_reference":{},"location":{},"width":"0.000000","height":"0.000000","depth":"0.000000","weight":"0.000000","quantity_discount":"0","ean13":"333456789111","isbn":{},"upc":{},"cache_is_pack":"0","cache_has_attachments":"0","is_virtual":"0","state":"1","on_sale":"0","online_only":"0","ecotax":"0.000000","minimal_quantity":"1","price":"16.510000","wholesale_price":"4.950000","unity":{},"unit_price_ratio":"0.000000","additional_shipping_cost":"0.00","customizable":"0","text_fields":"0","uploadable_files":"0","active":"1","redirect_type":"404","id_type_redirected":"0","available_for_order":"1","available_date":"0000-00-00","show_condition":"0","condition":"new","show_price":"1","indexed":"1","visibility":"both","advanced_stock_management":"0","date_add":"2017-03-16 14:36:24","date_upd":"2017-12-01 13:01:13","pack_stock_type":"3","meta_description":{"language":{"@attributes":{"id":"1"}}},"meta_keywords":{"language":{"@attributes":{"id":"1"}}},"meta_title":{"language":{"@attributes":{"id":"1"}}},"link_rewrite":{"language":"gebleekte-T-shirts-met-korte-mouwen"},"name":{"language":"Gebleekte T-shirts met Korte Mouwen"},"description":{"language":"
Fashion maakt goed ontworpen collecties sinds 2010. Het merk biedt vrouwelijke combineerbare kleding en statement dresses en heeft een pr\u00eat-\u00e0-porter collectie ontwikkeld met kledingstukken die niet in een garderobe mogen ontbreken. Het resultaat? Cool, gemakkelijk, easy, chique met jeugdige elegantie en een duidelijk herkenbare stijl. Alle prachtige kledingstukken worden met de grootste zorg gemaakt in Itali\u00eb. Fashion breidt zijn aanbod uit met accessoires zoals schoenen, hoeden, riemen!<\/p>"},"description_short":{"language":"

Gebleekt T-shirt met korte mouwen en hoge halslijn. Zacht en elastisch materiaal zorgt voor een comfortabele pasvorm. Maak het af met een strooien hoed en u bent klaar voor de zomer!<\/p>"},"available_now":{"language":"Op voorraad"},"available_later":{"language":{"@attributes":{"id":"1"}}},"associations":{"categories":{"@attributes":{"nodeType":"category","api":"categories"},"category":[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]},"images":{"@attributes":{"nodeType":"image","api":"images"},"image":[{"id":"1"},{"id":"2"},{"id":"3"},{"id":"4"}]},"combinations":{"@attributes":{"nodeType":"combination","api":"combinations"},"combination":[{"id":"1"},{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"},{"id":"6"}]},"product_option_values":{"@attributes":{"nodeType":"product_option_value","api":"product_option_values"},"product_option_value":[{"id":"1"},{"id":"13"},{"id":"14"},{"id":"2"},{"id":"3"}]},"product_features":{"@attributes":{"nodeType":"product_feature","api":"product_features"},"product_feature":[{"id":"5","id_feature_value":"5"},{"id":"6","id_feature_value":"11"},{"id":"7","id_feature_value":"17"}]},"tags":{"@attributes":{"nodeType":"tag","api":"tags"}},"stock_availables":{"@attributes":{"nodeType":"stock_available","api":"stock_availables"},"stock_available":[{"id":"1","id_product_attribute":"0"},{"id":"11","id_product_attribute":"1"},{"id":"12","id_product_attribute":"2"},{"id":"13","id_product_attribute":"3"},{"id":"22","id_product_attribute":"4"},{"id":"23","id_product_attribute":"5"},{"id":"24","id_product_attribute":"6"}]},"accessories":{"@attributes":{"nodeType":"product","api":"products"}},"product_bundle":{"@attributes":{"nodeType":"product","api":"products"}}}},
简化结构
products {
product {
        id:
        name:
        category:
        ...
        @attributes {
            id:
            language:
            ...
        }
        @attributes {
            {"nodeType":"product_option_value","api":"product_option_values"},"product_option_value":[
                {"id":"1"},
                {"id":"11"},
                {"id":"8"}, 
                {"id":"2"},
                {"id":"3"}
                ]
            },
        }
    }
}

在AngularJS中,使用$http.get()函数,我能够检索数据并使用ng-repeat和绑定组合来显示产品名称。现在我想访问@attribute值等信息。但是我该如何访问它们?是否有特定的方法可以做到这一点?还是纯粹通过访问JSON对象的深度级别来完成?

产品的AngularJS函数:

$http.get('config/get/getProducts.php', {cache: true}).then(function (response) {
        $scope.products = response.data.products.product
    });

那么在 <html> 中我只需使用:

<div ng-if="product.active == 1" class="productimg col-4" ng-repeat="product in products | filter : {id_category_default: catFilter.id}: true | filter:productSearch | filter:product.name | orderBy: 'name'">
    <p ng-bind="product.name.language"></p>
</div>

更新:01/02/2018 读完并测试了一些评论后,我得出了一个合理的解决方案。我能够访问@attributes和associations值,但我遇到了一个新问题。每个过滤器返回的结果都是多个"id"值。看下面的示例。

<div class="col-lg-3" ng-repeat="value in products">
    <p ng-bind="value.associations.categories.category"></p>
</div>

返回:

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"}]

[{"id":"2"},{"id":"3"},{"id":"4"},{"id":"7"}]

每行 [.. ..] 代表不同的产品。现在我需要获取这些值,仅作为它们所表示的数字,以便与不同表格中对应的id值进行比较。一个好的结果应该是:

2, 3, 4, 5

我该如何得到这个解决方案?

如果有人对此感兴趣,我正在尝试通过prestashop webservice从prestashop安装中检索产品的option_values id和category id。


我在这里没有看到其他选择。你将不得不按深度级别访问。如果你知道JSON结构,你可以解析并转换成更方便的结构。这样你只需要做一次,就可以随处访问。 - Ashish
@Ashish,你觉得我一直在尝试做什么? - Deathstorm
4个回答

8

我理解您想要使用ng-repeat来处理嵌套的JSON对象。您需要使用多个重复器,因为单个重复项可以包含多个子项,您希望将其显示出来。

因此,据我所见,以下内容应该可以正常工作:

<div ng-if="product.active == 1" class="productimg col-4" ng-repeat="product in products | filter : {id_category_default: catFilter.id}: true | filter:productSearch | filter:product.name | orderBy: 'name'">
    <p ng-bind="product.name.language"></p>
    <table ng-repeat="cat in product.associations.categories">
        <tr ng-repeat="attr in cat.@attributes">
            <td >{{attr.nodeType}}</td>
            <td >{{attr.api}}</td>
        </tr>
    </table>
</div>

请看这里:https://www.aspsnippets.com/Articles/AngularJS-Using-ng-repeat-with-Complex-Nested-JSON-objects.aspx


这是一个不错的尝试,但很遗憾对我来说并没有起作用。首先,在ng-repeat中不能使用@符号。我会用其他方法尝试这个例子,无论如何,谢谢! - Deathstorm

6

我认为你唯一的问题是使用点符号访问@attributes,例如product.associations.categories.@attributes

这不是有效的JavaScript语法,因此您应该使用方括号符号访问这些属性。

像这样:product.associations.categories['@attributes']


5
从您的问题中,我理解到问题是在ng-repeat中访问@attribute属性。请参见以下示例,展示使用ng-repeat访问@attribute值,我们也可以使用方括号表示法而不是点表示法来访问对象属性,更多信息请阅读这里
如果我的答案有助于解决您的问题,请告诉我,或者如果我在答案中漏掉了什么,请告诉我。

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

app.controller('MainCtrl', function($scope) {
  $scope.products = [{
    "id": "1",
    "id_manufacturer": "1",
    "id_supplier": "1",
    "id_category_default": "5",
    "new": {

    },
    "cache_default_attribute": "1",
    "id_default_image": "1",
    "id_default_combination": "1",
    "id_tax_rules_group": "1",
    "position_in_category": "0",
    "manufacturer_name": "Fashion Manufacturer",
    "quantity": "0",
    "type": "simple",
    "id_shop_default": "1",
    "reference": "demo_1",
    "supplier_reference": {

    },
    "location": {

    },
    "width": "0.000000",
    "height": "0.000000",
    "depth": "0.000000",
    "weight": "0.000000",
    "quantity_discount": "0",
    "ean13": "333456789111",
    "isbn": {

    },
    "upc": {

    },
    "cache_is_pack": "0",
    "cache_has_attachments": "0",
    "is_virtual": "0",
    "state": "1",
    "on_sale": "0",
    "online_only": "0",
    "ecotax": "0.000000",
    "minimal_quantity": "1",
    "price": "16.510000",
    "wholesale_price": "4.950000",
    "unity": {

    },
    "unit_price_ratio": "0.000000",
    "additional_shipping_cost": "0.00",
    "customizable": "0",
    "text_fields": "0",
    "uploadable_files": "0",
    "active": "1",
    "redirect_type": "404",
    "id_type_redirected": "0",
    "available_for_order": "1",
    "available_date": "0000-00-00",
    "show_condition": "0",
    "condition": "new",
    "show_price": "1",
    "indexed": "1",
    "visibility": "both",
    "advanced_stock_management": "0",
    "date_add": "2017-03-16 14:36:24",
    "date_upd": "2017-12-01 13:01:13",
    "pack_stock_type": "3",
    "meta_description": {
      "language": {
        "@attributes": {
          "id": "1"
        }
      }
    },
    "meta_keywords": {
      "language": {
        "@attributes": {
          "id": "1"
        }
      }
    },
    "meta_title": {
      "language": {
        "@attributes": {
          "id": "1"
        }
      }
    },
    "link_rewrite": {
      "language": "gebleekte-T-shirts-met-korte-mouwen"
    },
    "name": {
      "language": "Gebleekte T-shirts met Korte Mouwen"
    },
    "description": {
      "language": "Fashion maakt goed ontworpen collecties sinds 2010. Het merk biedt vrouwelijke combineerbare kleding en statement dresses en heeft een pr\u00eat-\u00e0-porter collectie ontwikkeld met kledingstukken die niet in een garderobe mogen ontbreken. Het resultaat? Cool, gemakkelijk, easy, chique met jeugdige elegantie en een duidelijk herkenbare stijl. Alle prachtige kledingstukken worden met de grootste zorg gemaakt in Itali\u00eb. Fashion breidt zijn aanbod uit met accessoires zoals schoenen, hoeden, riemen!<\/p>"
    },
    "description_short": {
      "language": "Gebleekt T-shirt met korte mouwen en hoge halslijn. Zacht en elastisch materiaal zorgt voor een comfortabele pasvorm. Maak het af met een strooien hoed en u bent klaar voor de zomer!<\/p>"
    },
    "available_now": {
      "language": "Op voorraad"
    },
    "available_later": {
      "language": {
        "@attributes": {
          "id": "1"
        }
      }
    },
    "associations": {
      "categories": {
        "@attributes": {
          "nodeType": "category",
          "api": "categories"
        },
        "category": [{
            "id": "2"
          },
          {
            "id": "3"
          },
          {
            "id": "4"
          },
          {
            "id": "5"
          }
        ]
      },
      "images": {
        "@attributes": {
          "nodeType": "image",
          "api": "images"
        },
        "image": [{
            "id": "1"
          },
          {
            "id": "2"
          },
          {
            "id": "3"
          },
          {
            "id": "4"
          }
        ]
      },
      "combinations": {
        "@attributes": {
          "nodeType": "combination",
          "api": "combinations"
        },
        "combination": [{
            "id": "1"
          },
          {
            "id": "2"
          },
          {
            "id": "3"
          },
          {
            "id": "4"
          },
          {
            "id": "5"
          },
          {
            "id": "6"
          }
        ]
      },
      "product_option_values": {
        "@attributes": {
          "nodeType": "product_option_value",
          "api": "product_option_values"
        },
        "product_option_value": [{
            "id": "1"
          },
          {
            "id": "13"
          },
          {
            "id": "14"
          },
          {
            "id": "2"
          },
          {
            "id": "3"
          }
        ]
      },
      "product_features": {
        "@attributes": {
          "nodeType": "product_feature",
          "api": "product_features"
        },
        "product_feature": [{
            "id": "5",
            "id_feature_value": "5"
          },
          {
            "id": "6",
            "id_feature_value": "11"
          },
          {
            "id": "7",
            "id_feature_value": "17"
          }
        ]
      },
      "tags": {
        "@attributes": {
          "nodeType": "tag",
          "api": "tags"
        }
      },
      "stock_availables": {
        "@attributes": {
          "nodeType": "stock_available",
          "api": "stock_availables"
        },
        "stock_available": [{
            "id": "1",
            "id_product_attribute": "0"
          },
          {
            "id": "11",
            "id_product_attribute": "1"
          },
          {
            "id": "12",
            "id_product_attribute": "2"
          },
          {
            "id": "13",
            "id_product_attribute": "3"
          },
          {
            "id": "22",
            "id_product_attribute": "4"
          },
          {
            "id": "23",
            "id_product_attribute": "5"
          },
          {
            "id": "24",
            "id_product_attribute": "6"
          }
        ]
      },
      "accessories": {
        "@attributes": {
          "nodeType": "product",
          "api": "products"
        }
      },
      "product_bundle": {
        "@attributes": {
          "nodeType": "product",
          "api": "products"
        }
      }
    }
  }];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MainCtrl" ng-app="myapp">
  <div ng-if="product.active == 1" class="productimg col-4" ng-repeat="product in products | filter : {id_category_default: catFilter.id}: true | filter:productSearch | filter:product.name | orderBy: 'name'">
    <p ng-bind="product.name.language"></p>
    <div ng-repeat="(key,value) in product['meta_title']['language']['@attributes']">
      Key: {{key}} , Value: {{value}}
    </div>
  </div>
</div>


3
您显然有两种解决问题的选择:
  1. 预格式化响应对象,以便JSON中的所有键都是JS接受的标识符。但在您的情况下,这将是徒劳无功的工作。
  2. 第二个选择是使用Object[fieldName]表示法而不是Object.fieldName,因为JSON中的键也可以是数字。请注意,JS中的数组是索引对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接