在MEANJS中的CRUD中使用URL中的slugs

时间:2014-12-26 18:00:32

标签: node.js express mean mean-stack meanjs

我需要在URL中使用slugs而不是文章ID,所以我在meanjs给出的文章示例中更改了一些内容,但我有问题,我可以列出,查看和编辑,但我可以'创造新的。 我不熟悉MEAN堆栈,所以我很可能在修改中遇到了一些错误,但我可以想办法让它工作。

在创建文章时从标题生成slug。我也想编辑,但如果我也要编辑slug字段,编辑功能也会停止工作......

代码来自使用垂直模块的meanjs的0.4分支。

在articles.client.service.js中,如果我改变:

angular.module('articles').factory('Articles', ['$resource',
    function($resource) {
        return $resource('api/articles/:articleSlug', {
            articleSlug: '@slug'
        }, {
            update: {
                method: 'PUT'
            }
        });
    }
]);

有:

angular.module('articles').factory('Articles', ['$resource',
    function($resource) {
        return $resource('api/articles/:articleSlug', {
            articleSlug: '@_id'
        }, {
            update: {
                method: 'PUT'
            }
        });
    }
]);

创建功能开始工作,但编辑功能停止... -.-

任何帮助都会受到赞赏。感谢

这是我的 articles.server.routes.js

'use strict';

/**
 * Module dependencies.
 */
var articlesPolicy = require('../policies/articles.server.policy'),
    articles = require('../controllers/articles.server.controller');

module.exports = function(app) {
    // Articles collection routes
    app.route('/api/articles').all(articlesPolicy.isAllowed)
        .get(articles.list)
        .post(articles.create);

    // Single article routes
    app.route('/api/articles/:articleSlug').all(articlesPolicy.isAllowed)
        .get(articles.read)
        .put(articles.update)
        .delete(articles.delete);

    // Finish by binding the article middleware
    app.param('articleSlug', articles.articleBySlug);
};

这是我的 articles.client.service.js

'use strict';

//Articles service used for communicating with the articles REST endpoints
angular.module('articles').factory('Articles', ['$resource',
    function($resource) {
        return $resource('api/articles/:articleSlug', {
            articleSlug: '@slug'
        }, {
            update: {
                method: 'PUT'
            }
        });
    }
]);

这是我的 articles.client.controller.js

'use strict';

angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles',
    function($scope, $stateParams, $location, Authentication, Articles) {
        $scope.authentication = Authentication;

        $scope.create = function() {
            var article = new Articles({
                slug: this.title.toLowerCase().replace(/ /g, '-'),
                title: this.title,
                content: this.content
            });
            article.$save(function(response) {
                $location.path('articles/' + response.slug);

                $scope.slug = '';
                $scope.title = '';
                $scope.content = '';
            }, function(errorResponse) {
                $scope.error = errorResponse.data.message;
            });
        };

        $scope.remove = function(article) {
            if (article) {
                article.$remove();

                for (var i in $scope.articles) {
                    if ($scope.articles[i] === article) {
                        $scope.articles.splice(i, 1);
                    }
                }
            } else {
                $scope.article.$remove(function() {
                    $location.path('articles');
                });
            }
        };

        $scope.update = function() {
            var article = $scope.article;

            article.$update(function() {
                $location.path('articles/' + article.slug);
            }, function(errorResponse) {
                $scope.error = errorResponse.data.message;
            });
        };

        $scope.find = function() {
            $scope.articles = Articles.query();
        };

        $scope.findOne = function() {
            $scope.article = Articles.get({
                articleSlug: $stateParams.articleSlug
            });
        };

    }
]);

这是我的 articles.server.controller.js

'use strict';

/**
 * Module dependencies.
 */
var _ = require('lodash'),
    path = require('path'),
    mongoose = require('mongoose'),
    Article = mongoose.model('Article'),
    errorHandler = require(path.resolve('./modules/core/server/controllers/errors.server.controller'));

/**
 * Create a article
 */
exports.create = function(req, res) {
    var article = new Article(req.body);
    article.user = req.user;

    article.save(function(err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(article);
        }
    });
};

/**
 * Show the current article
 */
exports.read = function(req, res) {
    res.json(req.article);
};

/**
 * Update a article
 */
exports.update = function(req, res) {
    var article = req.article;

    article.title = req.body.title;
    article.content = req.body.content;

    article.save(function(err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(article);
        }
    });
};

/**
 * Delete an article
 */
exports.delete = function(req, res) {
    var article = req.article;

    article.remove(function(err) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(article);
        }
    });
};

/**
 * List of Articles
 */
exports.list = function(req, res) {
    Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) {
        if (err) {
            return res.status(400).send({
                message: errorHandler.getErrorMessage(err)
            });
        } else {
            res.json(articles);
        }
    });
};

/**
 * Article middleware
 */

exports.articleBySlug = function(req, res, next, slug) {
    Article.findOne({'slug': slug}).populate('user', 'displayName').exec(function(err, article) {
        if (err) return next(err);
        if (!article) return next(new Error('Failed to load article ' + slug));
        req.article = article;
        next();
    });
};

1 个答案:

答案 0 :(得分:1)

我克隆了0.4.0分支,这就是我所做的工作,以便在各种情况下使用slug进行路由。

1-将slug添加到文章架构并确保其唯一article.server.model.js

slug: {
    type: String,
    default: '',
    trim: true,
    unique: true,
    required: 'Slug cannot be blank'
}

2-重新考虑文章控制器中的更新方法以包括slug:

  exports.update = function(req, res) {
      var article = req.article;

      article = _.extend(article , req.body);

      article.save(function(err) {
          if (err) {
              return res.status(400).send({
                  message: errorHandler.getErrorMessage(err)
              });
          } else {
              res.json(article);
          }
      });
  };

3-向文章控制器添加一个方法,通过slug(或req.query中的任何内容)查找文章

exports.readBySlug = function(req , res){
    Article.findOne(req.query).populate('user',
    'displayName').exec(function(err, article) {
    if (err) {
        return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
        });
        } else {
        res.json(article);
        }
    });
};

3-然后添加指向该方法的路由(确保在路由配置开头添加路由或至少在更新之前添加路由)

app.route('/api/articles/read-slug').get(articlesPolicy.isAllowed ,
    articles.readBySlug);

4-在articlePolicy中更改策略以允许GET到该路由:

exports.invokeRolesPolicies = function() {
    acl.allow([{
        roles: ['admin'],
        allows: [{
            resources: '/api/articles',
            permissions: '*'
        }, {
            resources: '/api/articles/:articleId',
            permissions: '*'
        }]
    }, {
        roles: ['user'],
        allows: [{
            resources: '/api/articles',
            permissions: ['get', 'post']
        }, {
            resources: '/api/articles/:articleId',
            permissions: ['get']
        }]
    }, {
        roles: ['guest'],
        allows: [{
            resources: '/api/articles',
            permissions: ['get']
        }, {
            resources: '/api/articles/:articleId',
            permissions: ['get']
        }]
    }, {
        roles: ['admin','user','guest'],
        allows: [{
            resources: '/api/articles/read-slug',
            permissions: ['get']
        }]
    }]);
};

在前端:

1-更改文章路线中的路线以使用slug而不是id:

    state('articles.view', {
        url: '/:articleSlug',
        templateUrl: 'modules/articles/views/view-article.client.view.html'
    }).
    state('articles.edit', {
        url: '/:articleSlug/edit',
        templateUrl: 'modules/articles/views/edit-article.client.view.html'
    });

2-在视图中更改链接以反映路线更改article.view({articleSlug: article.slug},同样适用于article.edit

3-在文章服务中添加方法以通过slug获取文章:

    return $resource('api/articles/:articleId/:controller', {
        articleId: '@_id'
    }, {
        update: {
            method: 'PUT'
        } ,
        getBySlug: {
            method: 'GET',
            params: {
              controller: 'read-slug'
            }
      }
    });

4-重新考虑文章控制器中的findOne方法,以使用我们刚刚定义的方法(在文章控制器中):

    $scope.findOne = function() {
        $scope.article = Articles.getBySlug({
            slug: $stateParams.articleSlug
        });

5-最后重新考虑更新并创建以包含slug(在文章控制器中):

    $scope.update = function() {
        var article = $scope.article;
        article.slug = article.title.toLowerCase().replace(/ /g, '-');
      console.log(article);
        article.$update(function() {
            $location.path('articles/' + article.slug);
        }, function(errorResponse) {
            $scope.error = errorResponse.data.message;
        });
    };


    $scope.create = function() {
        var article = new Articles({
            slug: this.title.toLowerCase().replace(/ /g, '-'),
            title: this.title,
            content: this.content
        });
        article.$save(function(response) {
            $location.path('articles/' + response.slug);

            $scope.title = '';
            $scope.content = '';
        }, function(errorResponse) {
            $scope.error = errorResponse.data.message;
        });
    };