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

traversing js object properties adds quotes to strings in jade view

本文关键字:属性 字符串 添加 加引号 对象 js jade 视图 遍历      更新时间:2023-09-26

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

我可能会得到这个数据:

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

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

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
});

最后我将它显示在jade视图中:

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)中不存在。遍历就是把它们相加。我使用'plain' json模块,它工作得很好。

猫鼬的数据看起来很简单,但当然在原型上有很多属性。如果我没有从结果集中省略'_id'(类型bson/objectid)属性,也可以遍历摊位。

所以遍历似乎有猫鼬数据的问题…为什么会这样?我该怎么补救呢?


EDIT

我找到了一个解决方案:

在过滤之前,我这样做: var json = JSON.parse(JSON.stringify(results)); var filtered = filterLanguage(lang, json); 这删除了引号,但我不确定它到底是做什么的。以某种方式将猫鼬结果转换为JSON?

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;
}));

看看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' } } } }

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