【问题标题】:Node.js How to display more than one category of articles on a pageNode.js 如何在一个页面上显示多个类别的文章
【发布时间】:2018-01-15 04:57:43
【问题描述】:

我想通过 .limit() 函数限制每个类别可以显示的帖子数量,但我不知道如何做到这一点。

我正在使用 Mongoose 和 Express。

到目前为止,我的代码如下。

router.get('/', function (req, res) {
  MainArticle.find({ category: ['Worldwide', 'U.S. News'] },  function (err, mainArticles) {
    if (err) {
      console.log(err);
    } else {
      res.render('landing', { mainArticles: mainArticles });
    }
  });
});

如果我用 EJS 输出结果,它将显示两个类别的所有结果。如果我要限制,它只会限制在我设置的整数。

我不确定要传递什么,因此我可以在网页的不同部分显示这两篇文章,并限制显示的帖子数量。


router.get('/profile', function (req, res) {
  // Retrieve the desired count for each category (for example, through a query parameter) defaulting to some number as needed.
  var limit = req.query.limit || 10;

  // Create an object to hold the results
  var result = {};

  // Get data for the world wide category
  MainArticle.find({
      category: ['Worldwide'],
    })
    .limit(limit)
    .exec(function (err, worldwideArticles) {
      if (err) {
        console.log(err);
      } else {
        // Add the worldwide data to the result set
        result.worldwideArticles = worldwideArticles;

        // Get data for the US news category
        MainArticle.find({
            category: ['U.S. News'],
          })
          .limit(limit)
          .exec(function (err, usArticles) {
            if (err) {
              console.log(err);
            } else {
              result.usArticles = usArticles;

              // Hand the two different sets separately to the template
              // You will obviously have to change the template code to handle the new data structure of different categories
              res.render('profile', { result: result });
            }
          });
      }
    });
});

EJS

<script type="text/javascript">
   var json_data = <%= JSON.stringify( result ); %>
</script>

这显示“全球”的文章,限制为 10 篇文章。

  <ul>
    <% result.worldwideArticles.forEach(function(mainArticles){ %>
    <li>
      <div class="img-container">
          <a href="/articles/<%= mainArticles._id %>"><img src="<%= mainArticles.image %>" alt=""></a>
           <div class="title-container">
            <a href="/articles/<%= mainArticles._id %>"><%=mainArticles.title %></a>
          </div>
      </div>
     <% }); %>

【问题讨论】:

  • 查看filter.find 将返回第一个匹配对象或 null
  • 澄清一下,您希望将'Worldwide''U.S News' 设置在不同的键上,以便您的目标网页?
  • 是的,没错。

标签: javascript node.js express mongoose


【解决方案1】:

你可以看看我在这里是怎么做的。让我知道这是否有效。

router.get('/', (req, res) => {
  MainArticle
    .where('category')
    .in(['Worldwide', 'U.S. News'])
    .limit(10)
      .then(mainArticles => {
        res.render('landing', { mainArticles })
      })
      .catch(err => {
        console.log(err)
      })
  )
}

可能需要在此处进行选择,但我无法对其进行测试。如果它不起作用,只需在 .in 之后添加要选择的属性。像.select('name', 'age', 'tags') 甚至更好的.select({}) 但我不知道没有测试什么会起作用。我只是在这里关闭文档:

http://mongoosejs.com/docs/2.7.x/docs/finding-documents.html

读取查询 API 的另一种方法是:

router.get('/', (req, res) => {
  const fetchArticles = MainArticle.find({})

  fetchArticles
    .where('category')
    .in(['Worldwide', 'U.S. News'])
    .limit(10)
      .then(mainArticles => {
        res.render('landing', { mainArticles })
      })
      .catch(err => {
        console.log(err)
      })
  )
}

.. 或者如果你想变得花哨:

router.get('/', async (req, res) => {

    function getArticles() {
        return MainArticle
            .where('category')
            .in(['Worldwide', 'U.S. News'])
            .limit(10)
            .exec()
    }

    try {
        let mainArticles = await getArticles()
        res.render('landing', { mainArticles })
    } catch (error) {
        console.log(error)
    }
}

根据您的上次提交更新。

  router.get('/', async (req, res) => {

    function getWorldwideArticles() {
        return worldwideArticles
            .where('category')
            .in(['Worldwide'])
            .limit(10)
            .exec()
    }

    function getUSArticles() {
      return usArticles
          .where('category')
          .in(['U.S. News'])
          .limit(10)
          .exec()
    }

    try {
        let worldwideArticles = await getWorldwideArticles()
        let usArticles = await getUSArticles()
        res.render('landing', { worldwideArticles, usArticles })
    } catch (error) {
        console.log(error)
    }
  }

【讨论】:

  • 在 Chirag Ravindra 的帖子中,他使用了 result.worldwideArticles = WorldwideArticles;结果.usArticles = usArticles;帮助我分别检索这两个类别。我怎样才能用你的方法来实现呢?
  • 所以再看一遍;我们将所有内容都传递给主要文章,而我要做的是在 ejs 方面检查存在哪个类别,这就是为什么你看到我正在做 ['Worldwide', 'U.S.新闻'] 只需在一次查找中抓住我这两个。它更便宜。让我修改我的回复,让你更容易。也许它会让你大开眼界。
  • @MichaelSanders 我认为这应该可行。如果没有,请告诉我,如果您愿意,我们可以在 Skype 上进行屏幕共享。
  • 我收到错误“getWorldwideArticles 未定义”,它指的是“返回 WorldwideArticles”。如果我注释掉第一个函数,我会得到“usArticles is not defined”,指的是“return usArticles”。
  • 你可能需要做类似的事情:await Promise.all([ getWorldwideArticles(), getUSArticles() ]) 有点傻。
【解决方案2】:

我通过使用 Chirag Ravindra 发布和传递的内容解决了这个问题

<script type="text/javascript">
     var json_data = <%- JSON.stringify( result ); %>
 </script>

在我的 EJS 上的 forEach 语句上方,因为 EJS can't call variables from clientside

那我就用了

<% result.worldwideArticles.forEach(function(mainArticles){ %>
<% }); %>

<% result.usArticles.forEach(function(mainArticles){ %>
<% }); %>

我想在哪里发布这两个类别。

【讨论】:

  • 您介意粘贴您的整个路线以便我重构它吗? :D
  • 看看,如果我错过了什么,请告诉我。对这一切还是陌生的。
【解决方案3】:

执行此操作的一种方法是分别查询每个类别并通过在结果中的不同键上设置两个find 操作的结果来为模板构建结果。

router.get('/', function(req, res) {
  // Retrieve the desired count for each category (for example, through a query parameter) defaulting to some number as needed.
  var limit = req.query.limit || 10;

  // Create an object to hold the results
  var result = {};
  // Get data for the world wide category
  MainArticle.find({
      category: ['Worldwide']
    })
    .limit(limit)
    .exec(function(err, worldwideArticles) {
      if (err) {
        console.log(err);
      } else {
        // Add the worldwide data to the result set
        result.worldwideArticles = worldwideArticles;
        // Get data for the US news category
        MainArticle.find({
            category: ['U.S. News']
          })
          .limit(limit)
          .exec(function(err, usArticles) {
            if (err) {
              console.log(err);
            } else {
              result.usArticles = usArticles;
              // Hand the two different sets separately to the template
              // You will obviously have to change the template code to handle the new data structure of different categories
              res.render('landing', result);

            }
          });
      }
    });
});

【讨论】:

  • 这就是一些人所说的,回调地狱。
  • @JosephChambers 同意了。 exec 方法返回一个 Promise,这将是处理这个问题的理想方式。但是,OP 发布的代码使用了回调功能,因此我选择将答案保持在相同的格式以传达答案,而不会增加额外的复杂性。
  • 哦,是的。那是个很好的观点。也许他只是不理解我的例子,这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多