NodeJS:保存菜单顺序

时间:2014-04-15 09:59:09

标签: javascript node.js express mongoose pug

我在使用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浏览器。首页10,大约20,联系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');
                        }
                    });
                });
            }
        });
    });
});

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

3 个答案:

答案 0 :(得分:1)

要理解你想要的东西太难了,下面简要介绍一下我的理解。

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

现在你想change/modify/update某个页面的order(即Frontpage to 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();
          }
       });
});
});

答案 1 :(得分:1)

您询问是否使用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');
  });
});

答案 2 :(得分:0)

我解决了这个问题。通过这样做:

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()不会立即更新数据库吗?