4

我是 Web 开发的新手,并且使用 node 和 express 开发了一个 Web 服务器。我为此使用了 MVC 模式,模型是 sequelizejs 对象。但是,对于我的控制器,你目前几乎没有 OOP,我想知道一些编写控制器的 OO 方式,而不是使用匿名函数来服务请求:

app.get('/test',function(req,res){})

也许我可以通过使用 URL 和模型作为 HTTP 动词的属性和方法来为每个路由创建对象:

//Use test.model for interacting with model
app.get(test.URL,test.get);
app.post(test.URL,test.post);
app.put(test.URL,test.put);
app.patch(test.URL,test.patch);
app.delete(test.URL,test.delete);

但是,它看起来有点矫枉过正,因为大多数/所有以这种方式制作的控制器对象最终都会成为没有继承、多态性和重用的单例。

问题:有没有更好的 OO 方式来编写控制器?

4

4 回答 4

15

你可以有一个控制器类,它的构造函数接受一个 express 对象,为你设置路由。所以这是一个示例基Controller类:

/**
 * @param connect can either be Sencha Labs' `connect` module, or
 */
function Controller(express) {
  var self = this;
  var name = '/' + this._name;
  express.post(name, function (req, res, next) {
    self._create(req, res, next);
  });
  express.get(name, function (req, res, next) {
    self._read(req, res, next);
  });
  express.put(name + '/:id', function (req, res, next) {
    self._update(req, res, next);
  });
  express.delete(name + '/:id', function (req, res, next) {
    self._delete(req, res, next);
  });
}

// Since there aren't any protected variables in JavaScript, use
// underscores to tell other programmers that `name` is protected. `name`
// (or, more technically, `_name`) is still accessible, but at least, if a
// team is disciplined enough, they'd know better than to access variables
// with underscores in them.
Controller.prototype._name = '';

Controller.prototype._create = function (req, res, next) {
};

Controller.prototype._read = function (req, res, next) {
};

Controller.protoype._update = function (req, res, next) {
};

Controller.prototype._delete = function (req, res, next) {
};

Users然后,您可以通过从Controller“类”扩展来创建控制器:

function UsersController(express) {
  Controller.call(this, express);
}

// This is not the most perfect way to implement inheritance in JavaScript,
// this is one of the many ways.
UsersController.prototype = Controller.prototype;

UsersController.prototype._name = 'users'

// An example override of the base `Controller#create` method.
UsersController.prototype._create = function (req, res, next) {
  db.save(req.body, function (err) {
    if (err) res.send(500, err.message);
    res.redirect('/');
  });
};

UsersController.prototype._read = function (req, res, next) {
  db.read(function (err, users) {
    if (err) res.send(500, err.message);
    res.send(users);
  });
};

一旦你声明和定义了所有适当的控制器,你就可以开始在你的 express 应用程序中实现它们。

// Initialize a new instance of your controller.
var usersController = new UsersController(app);

PS:对于构造函数中的快速调用,还有另一种方法可以添加您的create, read, update,delete路由(以及任何其他路由)。一开始我只是不想让你感到困惑。

function Controller(express) {
  var name = '/' + this._name;
  express.post(name, this._create.bind(this));
  express.get(name, this._read.bind(this));
  express.put([name , ':id'].join('/'), this._update.bind(this));
  express.delete([name, ':id'].join('/'), this._delete.bind(this));
};
于 2013-09-06T06:56:11.153 回答
1

我在 TypeScript 中编写了一个简单的示例,展示了如何为快速应用程序编写控制器,同时考虑到面向对象的编程。它可以很容易地应用于 ES6:

服务器.ts

import * as express from 'express';
import {CategoryController} from 'src/view/CategoryController';

export default class Server {
  public app: express.Application;

  constructor() {
    this.app = express();
    this.app.get('/', (request, response) => response.send('Root page without OOP.'));
    // Using a controller to serve a view
    this.app.use('/categories', CategoryController);
  }
}

类别控制器.ts

import {Router, Request, Response} from 'express';

const router: Router = Router();

router.get('/', (request: Request, response: Response): Response => {
  const payload: { [index: string]: string[] } = {categories: ['CSS', 'HTML', 'JavaScript', 'TypeScript']};
  return response.json(payload);
});

export const CategoryController: Router = router;
于 2017-07-09T17:22:12.870 回答
0

不是真正的答案,但我创建了一个节点模块来处理自动设置快速路由。 动态路由

//app.js
require('dynamic-routes')(app, __dirname + '/routes/');

然后

//routes/index.js
module.exports = {
    priority: 1000, //this is the `/` handler, should it should be the last route.
    path: '/',

    //this function gets passed the express object one time for any extra setup
    init: function(app) { 
        app.head(function(req, res) {});
    },

    GET: function(req, res) {
        res.end('GET ');
    },

    POST: function(req, res) {
        res.json(req.data);
    }
};
于 2013-09-06T16:18:19.610 回答
0

以 OOP 方式组织 express 的一种方法是使用为此提供脚手架的现有框架。sails.js是目前最流行的 node MVC 框架,使用 express.js 进行路由。

于 2015-04-04T17:39:57.167 回答