我正在使用非常简单的Refify npm模块来处理循环结构JSON。它在Node.js中对循环结构JSON对象进行字符串化,然后发送给客户端。我的Angular前端接收字符串化的JSON,需要调用refify的parse
方法将其转换回可用的对象。
如何在Angular前端中包含refify节点模块,以便可以引用refify?
后端用法如下所示:
var refify = require("refify");
app.get("/api/entries, function(req, res){
var circularJSON = //a circular JSON object
res.send(refify.stringify(circularJSON));
});
前端参考看起来像这样:
$http.get("/api/entries").success(function(data){
$scope.entries = refify.parse(data);
});
最佳答案
这是Refify的分支版本,可以在node.js和浏览器中使用。
Forked Refify
您可以简单地下载index.js
并将其包含在AngularJS应用程序中。并使用它。
看到下面的代码,我在片段和示例的最后添加了整个分叉的index.js
文件。
(function(obj) {
if (typeof exports === 'undefined') {
obj.refify = refify;
} else {
module.exports = refify;
}
function refify(obj) {
var objs = [];
var paths = []
var keyStack = [];
var objStack = [];
return walk(obj);
function walk(it) {
if (typeof it !== 'object') {
return it;
}
objs.push(it);
paths.push(keyStack.slice())
objStack.push(it)
var copy = initCopy(it);
for (var k in it) {
keyStack.push(k);
var v = it[k];
var i = objs.indexOf(v);
if (i == -1) {
copy[k] = walk(v)
} else {
var $ref = '#/' + paths[i].join('/');
copy[k] = {
$ref: $ref
};
}
keyStack.pop();
}
objStack.pop();
return copy;
}
}
refify.parse = function(it) {
if (typeof it !== 'object') it = JSON.parse(it);
var keyStack = [];
var copy = initCopy(it);
walk(it);
return copy;
function walk(obj) {
if (typeof obj !== 'object') {
set(copy, keyStack.slice(), obj);
return;
}
for (var k in obj) {
keyStack.push(k);
var current = obj[k];
var objPath = parseRef(current);
while (objPath) {
current = get(copy, objPath);
objPath = parseRef(current);
}
if (current === obj[k]) {
// We did *not* follow a reference
set(copy, keyStack.slice(), initCopy(current));
walk(current);
} else {
// We *did* follow a reference
set(copy, keyStack.slice(), current);
}
keyStack.pop();
}
}
}
refify.stringify = function(obj, replacer, spaces) {
return JSON.stringify(refify(obj), replacer, spaces)
}
function parseRef(value) {
if (typeof value !== 'object') return false;
if (!value.$ref) return false;
var path = value.$ref == '#/' ? [] : value.$ref.split('/').slice(1);
return path
}
function get(obj, path) {
if (!path.length) return obj;
if (typeof obj !== 'object') return;
var next = obj[path.shift()];
return get(next, path);
}
refify.set = set;
function set(obj, path, value) {
if (path.length === 0) throw new Error("Cannot replace root object");
var key = path.shift();
if (!path.length) {
obj[key] = value;
return;
}
switch (typeof obj[key]) {
case 'undefined':
obj[key] = isNaN(parseInt(key, 10)) ? {} : [];
break;
case 'object':
break;
default:
throw new Error("Tried to set property " + key + " of non-object " + obj[key]);
}
set(obj[key], path, value);
}
function initCopy(obj) {
if (typeof obj !== 'object') return obj;
return Array.isArray(obj) ? [] : {}
}
}(this));
// Example with forked version
var obj = {
inside: {
name: 'Stackoverflow',
id: '98776'
}
};
obj.inside.parent = obj;
var refifyObject= refify(obj);
document.getElementById("out").innerHTML = JSON.stringify(refifyObject);
<div id="out"></div>