Sono stato in grado di risolvere i collegamenti "$ ref" nel mio codice json adattando il codice, questo blogger pubblicato, per essere conforme a Angular.
link
Ho creato un servizio angolare per risolvere il "$ ref" che ottengo dal serializzatore JSON di NewtonSoft.
// http://willseitz-code.blogspot.com/2013/01/javascript-to-deserialize-json-that.html
(function () {
'use strict';
angular
.module('app')
.factory('jsonPointerParseService', jsonPointerParseService);
jsonPointerParseService.$inject = [];
function jsonPointerParseService() {
var hashOfObjects = {};
var service = {
pointerParse: pointerParse
};
return service;
function collectIds(obj) {
if (jQuery.type(obj) === "object") {
if (obj.hasOwnProperty("$id")) {
hashOfObjects[obj.$id] = obj;
}
for (var prop in obj) {
collectIds(obj[prop]);
}
} else if (jQuery.type(obj) === "array") {
obj.forEach(function (element) {
collectIds(element);
});
}
}
function setReferences(obj) {
if (jQuery.type(obj) === "object") {
for (var prop in obj) {
if (jQuery.type(obj[prop]) === "object" &&
obj[prop].hasOwnProperty("$ref")) {
obj[prop] = hashOfObjects[obj[prop]["$ref"]];
} else {
setReferences(obj[prop]);
}
}
} else if (jQuery.type(obj) === "array") {
obj.forEach(function (element, index, array) {
if (jQuery.type(element) === "object" &&
element.hasOwnProperty("$ref")) {
array[index] = hashOfObjects[element["$ref"]];
} else {
setReferences(element);
}
});
}
}
// Set the max depth of your object graph because JSON.stringify will not be able to
// serialize a large object graph back to
function setMaxDepth(obj, depth) {
// If this is not an object or array just return there is no need to
// set its max depth.
if (jQuery.type(obj) !== "array" && jQuery.type(obj) !== "object") {
return obj;
}
var newObj = {};
// If this object was an array we want to return the same type in order
// to keep this variable's consistency.
if (jQuery.type(obj) === "array") {
newObj = [];
}
// For each object or array cut off its tree at the depth value by
// recursively diving into the tree.
angular.forEach(obj, function (value, key) {
if (depth == 1) {
newObj = null;
}
else if (jQuery.type(value) === "array") {
if (setMaxDepth(value, depth - 1)) {
newObj[key] = setMaxDepth(value, depth - 1)
} else {
newObj = [];
}
} else if (jQuery.type(value) === "object") {
if (setMaxDepth(value, depth - 1)) {
newObj[key] = setMaxDepth(value, depth - 1)
} else {
newObj = [];
}
} else {
newObj[key] = value;
}
}, newObj);
return newObj;
}
function pointerParse(obj, depth) {
var newObj = obj;
hashOfObjects = {};
collectIds(newObj);
setReferences(newObj);
if (depth) {
newObj = setMaxDepth(newObj, depth);
}
return newObj;
}
}
})();
L'utilizzo sarebbe come tale:
var newObj = jsonPointerParseService.pointerParse(obj);
Si prega di tenere presente, questo è un servizio angolare. Quindi l'ho iniettato in qualsiasi controller che ha bisogno di avere questi riferimenti risolti, e di conseguenza effettuare la chiamata a pointerParse ().
Si noti che se si desidera inviare questo oggetto al server, la chiamata JSON.stringify () del browser deve essere in grado di gestire un oggetto con riferimenti circolari. Per impostazione predefinita, nel mio caso, Angular non chiama JSON.stringify () con i parametri richiesti per essere in grado di stringificare un oggetto con riferimenti circolari. Quindi, in questo caso, suggerirei di postare solo una piccola porzione di dati e non restituire l'intero oggetto o creare un'istanza della propria chiamata per stringificare un oggetto come questo.
Infine, devo dire che trattare con $ ref è un dolore e ho deciso di mantenere la gestione dei riferimenti con solo array. Questo sembrava funzionare bene per me. Avevo ancora bisogno di accedere ai valori dell'array con $ values, tuttavia non dovevo preoccuparmi di risolvere i riferimenti e non dovevo preoccuparmi che il server facesse esplodere tentando di serializzare tutti i riferimenti circolari dell'oggetto a json.
json.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Arrays;
Aggiornamento: anche con i soli array di risoluzione ci sono ancora riferimenti che potrebbe essere necessario risolvere. In questi casi usa la funzione pointerParse () per prenderti cura di loro.