【问题标题】:NodeJS: Save menu orderNodeJS:保存菜单顺序
【发布时间】:2014-05-29 14:42:35
【问题描述】:

我在使用 Mongoose 在 NodeJS 中保存菜单顺序时遇到了一些问题。

首先我通过 Jade 循环出我的菜单结构:

form(method='post', action='/admin/pages/order')
    ul
        each page in pages
            li
                input(type='number', name='order', value= page.order)
                |  - 
                a(href='/admin/pages/edit/' + page._id)= page.title
                |  - 
                a(href='/admin/pages/delete/' + page._id) Delete page

    button Save order

page.order 描述了页面的当前顺序。 IE。 Frontpage 10、About 20、Contact 30 等。如果我想要另一个订单,我应该能够将 Frontpage 移动到 25,这将把它放在 About 和 Contact 之间,但只要我保存。顺序乱了。

也许我错过了下面的一些代码或做错了什么?

这是我的存档:

var Page = require('../models/page');

app.post('/admin/pages/order', function(req, res) {
    var pageOrder = req.body.order;
    var counter = [];

    Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) {
        pages.forEach(function(page, index) {
            counter.push(true);

            page.order = 0;
            page.save();

            if (counter.length === pages.length) {
                counter = [];
                var count = 1;

                Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) {
                    pages.forEach(function(page, index) {
                        counter.push(true);

                        page.order = 10 * count++;
                        page.save();

                        if (counter.length === pages.length) {
                            res.redirect('/admin/pages');
                        }
                    });
                });
            }
        });
    });
});

如果您需要更多信息,请直接说。

【问题讨论】:

    标签: javascript node.js express mongoose pug


    【解决方案1】:

    你想要什么太难理解了,下面是我理解的简要说明。

    //You have following `pages` records : 
    {
    title : 'Frontpage'
    order:10
    }
    ,
    {
    title : 'About'
    order:20
    }
    ,
    {
    title : 'Contact'
    order:30
    }
    

    现在你想change/modify/update 某个页面的order(即首页到25)。

    如果我对您的理解正确,那么我建议您使用不同的路线来处理那些updates

    /*
    What the following handler does is :
    Whenever you attempt to change the page order, first of all it tries to get one with the same order and assign its order to the page's order that is going to be updated. (I hope it is clear enough)
    */
    app.put('/admin/pages/:pageId/order', function(req, res) {
    
    Page.findOne({order:req.body.order}, function(err, doc){
    
           Page.findById(req.params.pageId, function(err, page) {
              var pageOrder = page.order;
              page.order = req.body.order;
              page.save();
    
              if(doc) {
               doc.order = pageOrder;
               doc.save();
              }
           });
    });
    });
    

    【讨论】:

    • 感谢您的回答,并为解释感到抱歉。这几乎是我想要做的。执行我想立即更新我的所有页面,因为我点击了“保存订单”,并为所有这些页面设置了一个潜在的新订单。因为我的 req.body.order 将包含我所有页面当前订单的数组。有意义吗?
    【解决方案2】:

    我解决了这个问题。改为这样做:

    app.post('/admin/pages/order', function(req, res) {
        var pageOrder = req.body.order;
        var counter = [];
        var count = 1;
    
        Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) {
            pages.forEach(function(page, index) {
                counter.push(true);
    
                Page.findOneAndUpdate({order: page.order}, {order: pageOrder[index]}, true, function(err) {
                    if (err)
                        res.send(err);
                });
    
                if (counter.length === pages.length) {
                    counter = [];
    
                    Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) {
                        pages.forEach(function(page, index) {
                            counter.push(true);
    
                            page.order = count++ * 10;
                            page.save();
    
                            if (counter.length === pages.length) {
                                res.redirect('/admin/pages');
                            }
                        });
                    });
                }
            });
        });
    });
    

    我必须使用 findOneAndUpdate 来获取我的菜单的新列表。所以我可以用 count++ * 10 清理订单,然后将其保存到数据库中。

    这是最聪明的做法吗?并且 page.save() 不会立即更新数据库?

    【讨论】:

    • page.save 是一个异步函数 - 你可以通过回调调用它,它会在模型​​保存时被调用(或者如果有错误,它将是回调的第一个参数) .我认为更聪明的方法是手动对内存中的列表进行排序,然后进行 count++*10 清理工作,而不是将其推送到数据库,将其拉回排序,然后使用 count++*10 将其推回清理。
    • 好吧,很公平。正如您所说:如果它没有坏,请不要修复它:)。但由于我处于 Node 等的学习曲线中,我真的很想学习如何正确地做到这一点。我可以让您尝试使用异步和内存来执行此操作吗?如果它不是很多要求。我尝试了异步,但从来没有用它来解决这个问题。提前致谢
    • “with async”是指async 包?
    【解决方案3】:

    您询问了使用async 并在内存中进行第一次排序而不是两次访问数据库。你可以试试这个(我没有测试过)。它使用Underscore 进行排序。

    _ = require("underscore");
    async = require("async");
    
    // ...
    
    var newPageOrders = req.body.order;
    
    // Get the pages in their original order
    Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) {
      if (err) return res.send(err);
    
      // Set the order on the pages to the new order
      pages.forEach(function (page, index) {
        page.order = newPageOrders[index];
      });
    
      // Use the Underscore library to sort the list of pages by its new ordering
      pages = _.sortBy(pages, 'order');
    
      // Now that we've sorted the pages, normalize the order numbers
      pages.forEach(function (page, index) {
        page.order = index*10
      });
    
      // Save all of the pages
      async.forEach(pages, function (page, callback) {
        // Save the page. Pass in the callback which async provides us with,
        // so that async knows when the page is saved
        page.save(callback);
      }, function (err) {
        // This function is only called once all of the pages are saved
        if (err) res.send(err);
        else res.redirect('/admin/pages');
      });
    });
    

    【讨论】:

    • 我会接受这是一个正确的答案,是的,因为这正是我想要的 - 非常感谢先生:)。但是我可以在没有下划线包的情况下做到这一点吗?说 Page.find({}, {}, { sort: { 'order' : 1 } }, function(err, pages) { .... });然后再这样排序?
    • 但是我会再次进入我的记录。嗯:)
    • 你可以尝试在数组上使用native sort method,传入一个比较器函数,比如function(pageA, pageB) {return pageA.order - pageB.order;}
    • 非常感谢。你帮了大忙:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多