我在这里遇到了一个精神上有问题的问题,我在Backbone中使用一个集合检索了一个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或Date属性(对象的深度不同,对于某些属性,可能比两个级别更深)其他数据)。我在Backbone集合中有以下代码来过滤并返回一个新集合,其中包含适当过滤的内容:
findWhere: function (Attribute, Value)
{
return new Project.Collections.Fixtures(this.filter(function (fixture)
{
return eval('fixture.attributes.' + Attribute) == Value;
}));
}
这允许我在属性中指定对于任何深度的对象,我想要过滤哪个属性,以及我想要它等于什么。问题是,我真的不想使用“eval”来做这件事,但显然我不能将“[Attribute]”用于像“AwayTeam.TeamID”这样的东西,因为它不起作用。
有没有人知道我可以使用哪种方法来实现此功能而不使用eval?
答案 0 :(得分:9)
这样的东西可以让你遍历对象的层次结构来找到一个值:
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;
}));
}
一起玩的小提琴
答案 1 :(得分:1)
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的解决方案。
答案 2 :(得分:0)
我接受了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周期是否有很多好处,但我喜欢适当的递归函数
答案 3 :(得分:0)
如何使用eval()
这样:
var myObject = {
first: 'Some',
last: 'Person',
address: {
city: 'Melbourne',
country: 'Australia'
}
}
var propPath = 'address.city';
var city = eval("myObject."+propPath);
console.log(city); // = Melbourne