既然dojo有,何不把dojo的借鉴一下.######对dojo不是很熟悉,没时间仔细研究。。。######不错,我一直希望有人能够做这个事情,在客户端解析fastjson的应用。######回复 @gohsy : 谢谢的你支持。使用好了并参与其中,才是更好的使用开源方式。也就是所谓的社区能读能改。我打算开一个项目用javascript实现fastjson的引用解析,希望你能够参与其中。######很早就在项目中引入了温少侠的fastjson druid,绝对达到商业软件的水准了,屡用不爽,越用越爽。######
fastjson循环引用的文档:
https://github.com/alibaba/fastjson/wiki/%E5%BE%AA%E7%8E%AF%E5%BC%95%E7%94%A8 ######很高端。只是想知道,大部分语言的JSON API应该都不支持循环引用吧,那么循环引用是什么样的需求产生的?可以避免不?
######文章里面已经描述了,由hibernate生成的实体,包含着大量的关联引用,在稍大的一点的项目中,实体对象之间的关联关系会比较复杂,要么就手动处理有选择性的输出关联关系,要么就用fastjson这样能够处理循环引用的库,在数据使用方的底层,在做引用还原。######可以对每个域模型继承一个接口,接口提供一个将模型转为map的方法,map里可以包含引用,但也是对方转成map的,同时自己在转map那个方法里防止递归引用。######Ext.define('overrides.JSON', {
override : 'Ext.JSON',
decode : function(json, safe) {
me = this;
if (typeof me.JSON.retrocycle !== 'function') {
me.JSON.retrocycle = (function() {
'use strict';
var t_obj = typeof {}, t_arr = Object.prototype.toString
.apply([]), t_str = typeof "";
var walk = function(path, _xpath, array) {
if (path.startsWith('$')) // 基于xpath直接定位
return path;
else { // 相对回溯定位
var x, j = path.split('..'), k = -j.length
+ (array ? 2 : 1), last = j.slice(-1)[0]
.replace('/', '.');
x = k < 0 ? _xpath.slice(0, k) : _xpath.slice(0);
if (last && !last.startsWith('.')
&& !last.startsWith('['))
last = '.' + last;
path = x.join('.') + last;
}
return path; // 最终得到绝对xpath地址
};
return function($) {
var xpath = ['$'];
(function rez(value) {
var i, item, name, path, _x;
if (value && typeof value === t_obj) {
if (Object.prototype.toString.apply(value) === t_arr) {
for (i = 0; i < value.length; i += 1) {
item = value[i];
if (item && typeof item === t_obj) {
xpath.push(xpath.pop() + '[' + i + ']'); // 下标引用要合并分级
path = item.$ref;
if (typeof path === t_str)
value[i] = eval(walk(path, xpath,
true));
else
rez(item);
if (_x = xpath.pop())
xpath.push(_x.slice(0, _x
.indexOf('['))); // 下标引用还原分级
}
}
} else {
for (name in value) {
if (value.hasOwnProperty(name)
&& typeof value[name] === t_obj) {
xpath.push(name);
item = value[name];
if (item) {
path = item.$ref;
if (typeof path === t_str)
value[name] = eval(walk(path,
xpath));
else
rez(item);
}
xpath.pop();
}
}
}
}
})($);
return $;
}
})();
}
var isNative = function() {
var useNative = null;
return function() {
if (useNative === null) {
useNative = Ext.USE_NATIVE_JSON && window.JSON
&& JSON.toString() == '[object JSON]';
}
return useNative;
};
}();
var decodingFunction;
doDecode = function(json) {
return json ? eval("(" + json + ")") : "";
};
if (!decodingFunction) {
// setup decoding function on first access
decodingFunction = isNative() ? JSON.parse : doDecode;
}
try {
return this.JSON.retrocycle(decodingFunction(json));
} catch (e) {
if (safe === true) {
return null;
}
Ext.Error.raise({
sourceClass : "Ext.JSON",
sourceMethod : "decode",
msg : "我尝试解析 an invalid JSON String: " + json
});
}
}
});
Ext.decode = Ext.JSON.decode;
在Extjs 4.2 里的写法。放在与app目录平齐的overrides里面。
然后在APP.js里面加入下面的东西。
Ext.application({ name: 'admin', extend: 'admin.Application', requires: [ // 'overrides.grid.RowEditor' 'overrides.JSON' ], autoCreateViewport: true });
######
这个解析的算法还有BUG。就是当A引用B一个集合,A在引用B单个的时候解析出来可能B指向的A就会错误。
举个例子:客户与客户联系人。客户有一个客户联系人的集合的属性,客户还有一个主联系人的属性。同时客户联系人也指向客户有一个属性,当这种对应关系的时候解析就会出错!
我尝试着想要去解决,但是智商有限搞不了。求作者在查看一下。
######
引用来自“刘思作”的评论
这个解析的算法还有BUG。就是当A引用B一个集合,A在引用B单个的时候解析出来可能B指向的A就会错误。
举个例子:客户与客户联系人。客户有一个客户联系人的集合的属性,客户还有一个主联系人的属性。同时客户联系人也指向客户有一个属性,当这种对应关系的时候解析就会出错!
我尝试着想要去解决,但是智商有限搞不了。求作者在查看一下。
看来这个问题还是有人关注的哈。
你可以给点数据,我有空的时候的看看。