2015-05-03 36 views
2

我目前的工作,抓住内容和数据从不同的Web服务调用快车站点。用于呈现网站超级菜单的网站导航数据来自发送嵌套json结果集的端点,该结果集包含导航部分用于呈现视图的结构hrefs,titles。操纵端点JSON数据快递

这里是一个缩短的例子:

 { 
     "results": [ 
      { 
      "title": "My Cool Site", 
      "contents": [ 
       { 
       "title": "Fruits", 
       "contents": [ 
        { 
        "title": "index", 
        "path": "/my-cool-site/fruits", 
        "inode": "fc5dba53-b925-4933-869b-e8c68c89e8ab", 
        "href": "/my-cool-site/fruits/index.html" 
        }, 
        { 
        "title": "Apples", 
        "path": "/my-cool-site/fruits/apples", 
        "inode": "e67c34bb-9b1a-4c1b-8beb-df986827be27", 
        "href": "/my-cool-site/fruits/apples.html" 
        }, 
        { 
        "title": "Bananas", 
        "path": "/my-cool-site/fruits/bananas", 
        "inode": "e67c34bb-9b1a-4c1b-8beb-df986827be27", 
        "href": "/my-cool-site/fruits/bananas.html" 
        } 
       ], 
       "path": "/my-cool-site/fruits", 
       "inode": "89d90234-f955-4726-9116-a599b8c92138", 
       "href": "/my-cool-site/fruits" 
       }, 
       { 
       "title": "Vegetables", 
       "contents": [ 
        { 
        "title": "index", 
        "path": "/my-cool-site/vegetables", 
        "inode": "57d1af70-a674-4ec3-965a-7eb0e0da3c75", 
        "href": "/my-cool-site/vegetables/index.html" 
        }, 
        { 
        "title": "Broccoli", 
        "path": "/my-cool-site/vegetables/broccoli", 
        "inode": "57d1af70-a674-4ec3-965a-7eb0e0da3c75", 
        "href": "/my-cool-site/vegetables/broccoli.html" 
        }, 
        { 
        "title": "Brussel Sprouts", 
        "path": "/my-cool-site/vegetables/brussel-sprouts", 
        "inode": "57d1af70-a674-4ec3-965a-7eb0e0da3c75", 
        "href": "/my-cool-site/vegetables/brussel-sprouts.html" 
        }, 

       ], 
       "path": "/my-cool-site/vegetables", 
       "inode": "89d90234-f955-4726-9116-a599b8c92138", 
       "href": "/my-cool-site/vegetables" 
       } 
      ] 
      } 
     ] 
     } 

服务产生的导航树用于多个站点,所以你可以看到,像“HREF”一些数据:值中包含的上下文路径'/ my-cool-site',我想从导航中删除。例如,当我呈现导航链接,对于苹果的节点应该有一个HREF =“/水果/ apples.html”没有“/my-cool-site/fruits/apples.html”所以,我会怎样无论他们出现在哪里,都要对href值进行替换?

将如何做到这一点的最好方法是什么?在我的控制器/路由中,我正在调用以获取数据,然后将nav对象传递给我的视图。

client.get(navEndPointUrl, function(nav, response) { 
     res.render('templateName', { 
      nav: nav 
     }); 
    }); 

我是新来的节点/快递,所以我正在寻找最好的方式来处理这个问题的例子。在视图中处理它?将nav对象传递给lodash /下划线函数?对于后者,我是有在草堆中寻找针麻烦时,它可能出现在许多不同的嵌套位置(例如,有些链接可能是下的JSON 4-5嵌套的节点),还需要返回整个json对象,而不仅仅是它的一部分。用某种正则表达式来使用JSON.parse会更好吗?我不知道,我对这个问题感到头痛。

为了记录在案,我预计会有种种这些项目想出这个项目,所以就使之成为一个更广义的解决方案的任何指导,将不胜感激。

+0

我可以想到一些干净的通用方法来做到这一点。你使用的是什么模板引擎? –

+1

我正在使用Dust http://www.dustjs.com/ – nyanMatt

回答

1

删除的/my-cool-site出现从pathhref对象值。

function formatResults(data, path, keys) { 
    function format(data) { 
     var result = {} 
     if (_.isObject(data)) { 
      _.forOwn(data, function (value, key) { 
       if (_.contains(keys, key)) { 
        value = value.replace(path, ''); 
       } 
       result[key] = format(value); 
      }); 
     } else if (_.isArray(data)) { 
      result = _.map(array, format); 
     } else { 
      result = data; 
     } 
     return result; 
    } 

    return format(data); 
} 

var formattedResults = formatResults(json, '/my-cool-site', ['path', 'href']); 

console.log(formattedResults); 

http://jsfiddle.net/moogs/sq1qeojp/1/

遍历结果对象,你通常会在你的模板。

+0

谢谢,很好的回答! – nyanMatt

0

把手:

Handlebars可能是一个不错的选择,以佣工的优势和/或谐音功能来处理您的href性能。您的代码可能是这个样子:

var Handlebars = require('handlebars'); 

Handlebars.registerHelper('relative_to', function(rootPath) { 
    var relativePath = this.href; 
    if (relativePath.indexOf(rootPath) === 0) { 
     relativePath = relativePath.substr(rootPath.length); 
    } 
    return new Handlebars.SafeString(relativePath); 
}); 

var context = { 
    contents: [{ 
     "title": "index", 
     "path": "/my-cool-site/fruits", 
     "inode": "fc5dba53-b925-4933-869b-e8c68c89e8ab", 
     "href": "/my-cool-site/fruits/index.html" 
    }] 
}; 
var source = "{{#contents}}<a href={{relative_to '/my-cool-site'}}>{{title}}</a>{{/contents}}"; 
var template = Handlebars.compile(source); 

console.log(template(context)); 

,输出:

<a href=/fruits/index.html>index</a> 

Dust.js:

看起来Dust.js在过滤器的形式类似的功能: http://www.dustjs.com/docs/filter-api/和助手:http://www.dustjs.com/guides/dust-helpers/如果你想指定参数。

Dust.js真的是相当不错的:

function relativeTo(chunk, context, bodies, params) { 
    return chunk.tap(function(data) { 
     var relativePath = data; 
     if (relativePath.indexOf(params.path) === 0) { 
      relativePath = relativePath.substr(params.path.length); 
     } 
     return relativePath; 
    }).render(bodies.block, context).untap(); 
} 
dust.helpers.relativeTo = relativeTo; 

var data = { 
    "contents": [{ 
     "title": "index", 
     "href": "/my-cool-site/fruits/index.html" 
    }] 
}; 

var source = '{#contents}<a href="{@relativeTo path="/my-cool-site"}{href}{/relativeTo}">{title}</a>{/contents}'; 
var compiled = dust.compile(source, "intro"); 
dust.loadSource(compiled); 

dust.render("intro", data, function(err, out) { 
    if (err) throw err; 
    console.log(out); 
}); 

更新:看起来Dust.js甚至可以从数据上下文插你的帮手参数。所以建立关上面的代码中,你可以做这样的事情:

data.relativePath = "/my-cool-site"; 
var source = '{#contents}<a href="{@relativeTo path=relativePath}{href}{/relativeTo}">{title}</a>{/contents}'; 

这真的真棒:)

+0

感谢您的例子 - 当然看起来像这样可以完成工作。我想知道我是否应该这样做?我想这更像是一个哲学问题,但是有没有一种方法可以在更远的上游进行?例如,以便在我使用视图中的数据时,我只是输出{href}而不是使用大量内联过滤器/帮助器? – nyanMatt

+0

如果您想在视图或更上游的位置进行此操作,这真的取决于您。上游选项@Moogs有一个很好的答案。在哲学上,我认为你不应该为了表示/应用层的方便而改变或处理你的数据,应该在你的视图(或视图控制器)上按照它需要的方式格式化数据。 –

+0

哇,灰尘让你使用插值数据作为你的助手的参数。我已经在上面更新了我的答案。你已经有效地给我发了一个关于这个问题的Dust.js会议。我想我很喜欢它。谢谢:) –