遍历js对象属性会在jade视图中为字符串添加引号

时间:2016-09-25 19:11:01

标签: javascript node.js mongodb express mongoose

我正在使用npm模块traverse来过滤来自mongodb / mongoose的数据。

我可能会得到这些数据:

[ { rating: 5,
    title: { da: 'Web udvikling', en: 'Web Development' } },
  { rating: 5, title: { da: 'Node.js', en: 'Node.js' } } ]

'da'和'en'表示语言。我使用traverse来过滤当前语言之后的猫鼬数据,如下所示:

var filtered = filterLanguage(lang, results);
// filter json obj by language
var filterLanguage = function(language, obj) {
    return traverse(obj).map(function (item) {
        if (this.key === language) {
            this.parent.update(item);
        }
    });
};

然后我在我的模板中显示:

res.render('index', {
    skills: filtered.skills
});

最后我在玉石视图中显示它:

ul.list-group
    each skill, i in skills
        if i < 5
            li.list-group-item.sidebar-list-item= skill.title

不幸的是它显示引号:

<ul>
    <li>'Web Development'</li>
    <li>'Node.js'</li>
</ul>

未过滤的数据(results.skill.title.da)中没有这些引号。因此,遍历正在添加它们。我使用了'普通'json的模块,它运行得很好。

mongoose数据看似简单明了,但当然原型上有很多属性。如果我没有从结果集中省略'_id'(类型bson / objectid)属性,也会遍历停顿。

因此,遍历似乎有猫鼬数据的问题......为什么会这样?我该如何解决?

- 编辑 -

我找到了解决方案:

在过滤之前我这样做: var json = JSON.parse(JSON.stringify(results)); var filtered = filterLanguage(lang, json); 这删除了引号,但我不确定它的作用。以某种方式将mongoose结果转换为JSON?我们将非常感谢您的解释。

2 个答案:

答案 0 :(得分:0)

Mongoose文档中的字段是getter / setter,它们似乎混淆了traverse或Jade / Pug。

我发现的最短的方法似乎解决了所有问题,这非常难看:

var filtered = filterLanguage(lang, results.map(r => JSON.parse(JSON.stringify(r))));

更精细的版本:

var filtered = filterLanguage(lang, results.map(r => {
  let j = r.toJSON()
  j._id = j._id.toString()
  return j;
}));

答案 1 :(得分:0)

查看filterLanguage的正文是什么有用或理解为什么它被调用两次会有所帮助,但就目前而言,我认为你根本不需要使用traverse

如下所示的功能应该可以解决这个问题,如果数据更像树状,并且不像示例中所示那样平坦,我甚至可以将其扩展为工作。

const reduceByLang = (data, lang) => {
  // Look for a `lang` key in obj or
  // if not found but still an object, recurse
  const reduceByLangObj = (obj) => {
    Object.keys(obj).forEach((key) => {
      if (obj[key] === null) {
        return;
      }
      if (obj[key][lang]) {
        obj[key] = obj[key][lang]; // replace with desired lang
      } else if (typeof obj[key] === 'object') {
        reduceByLangObj(obj[key]); // recurse
      }
    });
    return obj;
  };

  if (Array.isArray(data)) {
    return data.map(reduceByLangObj);
  } else {
    return reduceByLangObj(data);
  }
};

请参阅JS Bin中的示例。

此外,如果可能的话,如果您经常进行此类型的选择,我会考虑将数据保存在不同的结构中:

{ ratings: x, locales: { en: { title: 'Y' }, { da: { title: 'Z' } } } }

也许,这样您就可以在查询本身和/或控制器中轻松选择所选语言。

编辑:检查是否为空。