我有一个在这里精神上的征税问题,在这里我有在骨干网使用集合检索的JSON对象。 这就是对象的样子:
{
"MatchID": "00000001",
"Date": "1970-01-01T00:00:00.000Z",
"OriginalID": "",
"Stage": {
"StageNumber": "0",
"StageType": "Stage Type"
},
"Round": {
"RoundNumber": "0",
"Name": "Round Name"
},
"Leg": "1",
"HomeTeam": {
"TeamID": "0",
"Name": "Home Team Name"
},
"AwayTeam": {
"TeamID": "0",
"Name": "Away Team Name"
},
"Venue": {
"VenueID": "0",
"Name": "Venu Name"
},
"Referee": null,
}
我想这个数据做的,就是将其过滤基于特定的属性,如Venue.Name或日期属性(它们是不同的深度进入的对象,可以为一些其他数据的更深两个级别) 。 我有一个主干内部集合下面的代码过滤,返回与适当过滤内容的新的集合:
findWhere: function (Attribute, Value)
{
return new Project.Collections.Fixtures(this.filter(function (fixture)
{
return eval('fixture.attributes.' + Attribute) == Value;
}));
}
这让我在哪个属性我想过滤的属性指定的,我希望它是等于为对象的任何深度的东西。 问题是,我真的不希望使用“EVAL”要做到这一点,但显然我不能用“[属性]”这样的事情“AwayTeam.TeamID”,因为这将无法正常工作。
有谁知道我可以用它来实现,而不使用eval此功能的方法?
像这样的东西会让你遍历对象的层次结构,以找到一个值:
var x = {
y: {
z: 1
}
};
function findprop(obj, path) {
var args = path.split('.'), i, l;
for (i=0, l=args.length; i<l; i++) {
if (!obj.hasOwnProperty(args[i]))
return;
obj = obj[args[i]];
}
return obj;
}
findprop(x, 'y.z');
你可以将其添加为您的方法Fixture
对象:
Fixture = Backbone.Model.extend({
findprop: function(path) {
var obj = this.attributes,
args = path.split('.'),
i, l;
for (i=0, l=args.length; i<l; i++) {
if (!obj.hasOwnProperty(args[i]))
return;
obj = obj[ args[i] ];
}
return obj;
}
});
并用它来提取值
var f = new Fixture();
f.findprop("HomeTeam.TeamID");
该findWhere
然后方法可以改写为
findWhere: function (Attribute, Value)
{
return new Project.Collections.Fixtures(this.filter(function (fixture){
return fixture.findprop(Attribute) === Value;
}));
}
和小提琴一起玩http://jsfiddle.net/nikoshr/wjWVJ/3/
在JavaScript对象属性可以由方括号来访问,字符串标识符以及标准的点表示法。
换句话说,这样的:
fixture.attributes.something
是一样的:
fixture.attributes["something"]
您也可以在以方括号传递变量名,变量的值作为关键来检索。
所以,你可以更改您的代码如下:
findWhere: function (Attribute, Value)
{
return new Project.Collections.Fixtures(this.filter(function (fixture)
{
return fixture.attributes[Attribute] === Value;
}));
}
当您在评论中指出,这只能处理一个级别的对象和属性。 为了得到嵌套的属性,你需要通过部分拆分“属性”变量和循环。 我喜欢@ nikoshr的该解决方案。
我把nikoshr答案,并增加了一些递归风骚的它:
var findprop = function (obj, path) {
var args = (typeof path === 'string') ? path.split('.') : path,
thisProperty = obj[args[0]];
if (thisProperty === undefined) { return; } //not found
args.splice(0, 1); //pop this off the array
if (args.length > 0) { return findprop(thisProperty, args); } //recurse
else {return thisProperty; }
};
我不知道是否有多少实惠递归CPU周期明智的,但我喜欢递归函数的时候都合适