Ember.js 余烬-数据嵌套在n个级别的深处,希望在从URL开始工作的路径中找到
对于恩伯来说,新成员是显而易见的,但我有一个问题,我认为其他人在学习时会遇到。基本上,我有一个传入的数据,它是一个标记的树层次结构。该应用程序基本上通过显示任何子节点来表示树的一个节点。单击一个子项,显示内容将替换为其子项的列表,依此类推。简单 通过URL手动刷新或其他方式进行路由时会出现问题: 如果用户要键入URL/tags/0,那么应用程序能够找到并提供“id”为0的标记的子项列表,因为我认为它是顶级的。但是,如果用户键入一个id为n-deep子级的URL,findBy方法将无法在数据中找到正确的节点 有findBy的递归版本吗 下面是相关的行和一些虚拟数据,来说明我关于层次结构的意思Ember.js 余烬-数据嵌套在n个级别的深处,希望在从URL开始工作的路径中找到,ember.js,Ember.js,对于恩伯来说,新成员是显而易见的,但我有一个问题,我认为其他人在学习时会遇到。基本上,我有一个传入的数据,它是一个标记的树层次结构。该应用程序基本上通过显示任何子节点来表示树的一个节点。单击一个子项,显示内容将替换为其子项的列表,依此类推。简单 通过URL手动刷新或其他方式进行路由时会出现问题: 如果用户要键入URL/tags/0,那么应用程序能够找到并提供“id”为0的标记的子项列表,因为我认为它是顶级的。但是,如果用户键入一个id为n-deep子级的URL,findBy方法将无法在数据中找到
App.Router.map(function(){
this.resource('tags', function () {
this.resource('tag', { path: ':tag_id' });
});
});
App.TagsRoute = Ember.Route.extend({
model: function() {
return tags;
}
});
App.TagRoute = Ember.Route.extend({
model: function(params) {
return tags.findBy('id', params.tag_id);
}
});
var tags = [{
weight: "plus size3",
untaggable: true,
id: '0',
label : "Existing Tags",
children: [{
id: "2",
weight: "plus size7",
label: "take-out"
},
{ id: "3",
weight: "plus size9",
label: "busy environment"
},
{ id: "4",
weight: "minus size9",
label: "casual-attire environment"
},
{ id: "5",
weight: "minus size0",
label: "classical-crossover-music"
},
{ id: "6",
weight: "plus size0",
label: "knowledgeable"
},
{ id: "7",
weight: "plus size3",
label: "busy environment"
}
]
},
{
untaggable: true,
id: '1',
weight: "minus size9",
label: "Add More Tags",
children: [{
untaggable: true,
id: '1111',
weight: "plus size9",
label: "interior",
children: [{
id: '8',
weight: "minus size9",
label: "modern",
},{
id: '9',
weight: "plus size3",
label: "classic",
},{
id: '10',
weight: "plus size3",
label: "dive",
}]
},{
untaggable: true,
id: '2222',
weight: "minus size9",
label: "exterior",
children: [{
id: '11',
weight: "minus size9",
label: "elegent exterior",
children: [{
id: '111',
weight: "minus size9",
label: "boroque exterior",
},{
id: '112',
weight: "plus size0",
label: "expensive exterior",
}]
},{
id: '12',
label: "dingy exterior",
children: [{
id: '121',
weight: "plus size0",
label: "shabby exterior",
},{
id: '122',
weight: "minus size6",
label: "dirty exterior",
}]
},{
id: '13',
weight: "plus size6",
label: "discrete exterior"
}]
},{
untaggable: true,
id: '3333',
weight: "minus size6",
label: "pricing",
children: [{
id: '14',
weight: "plus size3",
label: "$0-10 per person",
},{
id: '15',
weight: "minus size0",
label: "$10-20 per person",
},{
id: '16',
weight: "plus size9",
label: "$20-30 per person",
},{
id: '17',
weight: "minus size3",
label: "$30-40 per person",
},{
id: '18',
weight: "plus size9",
label: "$40-50 per person",
},{
id: '19',
weight: "minus size0",
label: "$50+ per person",
}]
},{
untaggable: true,
id: '4444',
weight: "plus size1",
label: "features",
children: [{
id: '20',
weight: "minus size0",
label: "beer-buckets"
},{
id: '21',
weight: "plus size8",
label: "big-screen-tv"},
{
id: '22',
weight: "zero size7",
label: "comedy"},
{
id: '23',
weight: "plus size9",
label: "drink-specials"},
{
id: '24',
weight: "zero size2",
label: "games",
children: [
{
id: '241',
weight: "minus size0",
label: "darts"},
{
id: '242',
weight: "plus size9",
label: "pool-table"}]},
{
id: '25',
weight: "plus size0",
label: "growlers"},
{
id: '26',
weight: "plus size3",
label: "happy-hour"},
{
id: '27',
weight: "minus size0",
label: "music"}]
},{
untaggable: true,
id: '5555',
weight: "plus size3",
label: "staff",
children: [{
id: '30',
weight: "minus size0",
label: "argumentative"},
{
id: '31',
weight: "plus size8",
label: "attentive"},
{
id: '32',
weight: "zero size5",
label: "available"},
{
id: '33',
weight: "plus size3",
label: "capable"},
{
id: '34',
weight: "minus size9",
label: "careless"},
{
id: '35',
weight: "plus size0",
label: "chatty"},
{
id: '36',
weight: "minus size6",
label: "cheerful"},
{
id: '37',
weight: "plus size3",
label: "competent"},
{
id: '38',
weight: "minus size0",
label: "considerate"},
{
id: '39',
weight: "minus size3",
label: "easy-going"},
{
id: '40',
weight: "plus size0",
label: "efficient"},
{
id: '41',
weight: "plus size3",
label: "engaging"},
{
id: '42',
weight: "plus size8",
label: "experienced"},
{
id: '43',
weight: "minus size1",
label: "friendly"}]
}]
}];
不幸的是,findBy没有递归版本。处理这种情况的标准方法是将对象存储在一个平面数据结构中:使用对象ID作为键的哈希或对象数组 您的标记树是一种任意/独特的数据结构,因此您有两种选择: 以更标准的方式表示数据,从而允许您使用数组和objects.finder函数的标准函数。 以树格式保存数据,但编写自己的递归 如果您选择选项2,您需要的是以下内容:
function findTagById(tags, id) {
var potentialMatch, match;
for (var i = 0; i < tags.length; i++) {
potentialMatch = tags[i];
if (potentialMatch.id === id) {
return potentialMatch;
}
if (potentialMatch.children) {
match = findTagById(potentialMatch.children, id);
if (match) {
return match;
}
}
}
}
在您的示例中,标签数据硬编码到应用程序中。然而,在现实世界中,使用Ember构建的绝大多数应用程序通常通过JSON API使用从web服务器接收的数据。Ember Data拥有各种可定制的序列化程序,负责获取从服务器接收到的可能结构异常的数据,并将其转换为可以包含在平面阵列中的单个模型。如果可以,我建议您使用余烬数据。非常感谢!听起来我应该使用余烬数据来转换它。同时,我也会试试你的功能。帽尖!