2017-12-18 100 views
17

Obecnie pracuję nad projektem, który używa API do pobierania, aktualizowania i usuwania danych. Interfejs API, którego używam, to prestashop API. Po odzyskaniu danych i aktualizacji niektórych rzeczy natknąłem się na problem. Jak powiedzieliśmy w dokumentacji, wszystkie dane wysyłane i pobierane przez API są z json i xml Ponieważ niektóre dane API mają różne poziomy w powrocie json, jak poziomy @attributes i @associations, wymyśliłem to pytanie.Atrybuty @ i @association JSON z js i/lub angularjs

Chodzi o to, że chciałbym uzyskać dostęp do tych danych i, w połączeniu z angularjs, chciałbym pokazać te dane. Pozwól, że pokażę ci szybki przykład tego, co próbuję osiągnąć.

Po pierwsze, powrót JSON byłby mniej więcej taki.

{"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"}}}}, 

Struktura uproszczony

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"} 
       ] 
      }, 
     } 
    } 
} 

pomocą funkcji $http.get() w angularjs jestem stanie odzyskać dane i użyć kombinacji ng powtarzania i wiązania pokazać product_names. Teraz chciałbym uzyskać dostęp do wartości @attribute i tak dalej. Ale jak mógłbym uzyskać do nich dostęp? Czy jest jakiś konkretny sposób na zrobienie tego? lub czy jest to czysto wykonane poprzez dostęp do poziomu głębokości obiektu JSON?

Funkcja angularjs dla produktów:

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

Następnie w <html> mogę po prostu użyć:

<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> 

UPDATE: 02.01.2018 Więc po przeczytaniu i testowania niektórych komentarzy mam rozsądne rozwiązanie. Jestem w stanie uzyskać dostęp do wartości @attributes i asocjacji, ale natknąłem się na nowy problem. Zwrot, który otrzymuję dla każdego filtra, ma wiele wartości "id". Spójrz na przykład poniżej.

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

Zwraca:

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

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

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

gdzie każdy rząd [.. ..] oznacza inny produkt. Teraz muszę uzyskać te wartości, jak tylko numery, które są one tak, że mogę je porównać z odpowiadającymi im wartościami z różnych tabel. Dobry wynik byłby następujący:

2, 3, 4, 5 

Pytanie brzmi, w jaki sposób mogę uzyskać dostęp do tego rozwiązania?

Jeśli ktokolwiek jest zainteresowany, dlaczego i jak. Próbuję pobrać identyfikator id option_values id z produktów z instalacji prestashop, a wszystko to za pośrednictwem usługi internetowej prestashop.

Dodałem kolejną nagrodę w tym pytaniu.

W przypadku jakichkolwiek pytań, proszę zapytać ich w komentarzach. Z góry dziękuję!

+0

Nie widzę tutaj żadnej innej opcji. Będziesz musiał uzyskać dostęp przez poziom głębokości. Jeśli znasz strukturę JSON, możesz przeanalizować i przekształcić ją w wygodniejszą strukturę. W ten sposób będziesz musiał zrobić to tylko raz i możesz uzyskać do nich dostęp wszędzie. – Ashish

+0

@Ashish Jak myślisz, co próbowałem zrobić? – Deathstorm

Odpowiedz

9

Jak rozumiem, chciałbyś użyć polecenia ng-repeat z zagnieżdżonymi obiektami JSON.Będziesz musiał użyć więcej niż jednego przemiennika, ponieważ pojedynczy powtarzany element może zawierać wiele własnych elementów, które chciałbyś wyświetlić.

Więc o ile widzę coś jak to powinno działać:

<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 [email protected]"> 
      <td >{{attr.nodeType}}</td> 
      <td >{{attr.api}}</td> 
     </tr> 
    </table> 
</div> 

Sprawdźcie tutaj: https://www.aspsnippets.com/Articles/AngularJS-Using-ng-repeat-with-Complex-Nested-JSON-objects.aspx

+0

To miła próba, ale niestety to nie działa. Przede wszystkim nie możesz użyć symbolu '@ 'w powtórzeniu ng. Spróbuję tego z tym przykładem na kilka innych sposobów, tak i tak dziękuję! – Deathstorm

5

Od swoje pytanie Rozumiem, że problemem jest dostęp do właściwości @attribute wewnątrz ng-repeat, poniżej przykład pokazujący wartości @attribute przy użyciu ng-repeat możemy również uzyskać dostęp do właściwości obiektu za pomocą bracket notation zamiast dot notation, czytaj więcej here.

Proszę dać mi znać, jeśli ta odpowiedź pomogła rozwiązać problem lub jeśli coś pominąłem w mojej odpowiedzi.

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>

7

Myślę, że jest tylko kwestią dostępu do @attributes z notacją dot jak tak [email protected]

ten nie jest prawidłowy javascript, więc zamiast tego należy użyć notacji Wspornik te atrybuty.

tak:

product.associations.categories['@attributes']

2

Trzeba wyraźnie dwie opcje rozwiązania tego problemy Ciebie:

  1. Preformatting obiekt odpowiedzi tak, że wszystkie klucze w JSON są JS akceptowane identyfikatorów. Ale to byłaby daremna praca w twoim scenariuszu.
  2. Po drugie stosuje się notację Object[fieldName] zamiast Object.fieldName, ponieważ kluczem w jsonie może być również liczba. Pamiętaj, że tablica w JS jest obiektem indeksowanym.