Nodejs,表达路由为es6类

问题描述 投票:13回答:4

我想稍微清理一下我的项目,现在我尝试将es6类​​用于我的路由。我的问题是这总是未定义的。

var express = require('express');
var app = express();

class Routes {
    constructor(){
        this.foo = 10
    }

    Root(req, res, next){
        res.json({foo: this.foo}); // TypeError: Cannot read property 'foo' of undefined
    }
}

var routes = new Routes();
app.get('/', routes.Root);
app.listen(8080);
javascript node.js express this nodes
4个回答
13
投票

尝试使用代码来固定this

app.get('/', routes.Root.bind(routes));

您可以使用下划线bindAll函数退出样板。例如:

var _ = require('underscore');

// ..

var routes = new Routes();
_.bindAll(routes)
app.get('/', routes.Root);

我还发现es7允许您以更优雅的方式编写代码:

class Routes {
    constructor(){
        this.foo = 10
    }

    Root = (req, res, next) => {
        res.json({foo: this.foo});
    }
}

var routes = new Routes();
app.get('/', routes.Root);

8
投票

发生这种情况是因为您已经将一个方法作为独立函数传递来表达。 Express不知道它来自哪个类,因此在调用方法时它不知道使用哪个值作为this

你可以用this强制bind的值。

app.get('/', routes.Root.bind(routes));

或者您可以使用替代构造来管理路线。在没有类的情况下,您仍然可以利用面向对象编程的许多语法优势。

function Routes() {
  const foo = 10;

  return {
    Root(req, res, next) {
      res.json({ foo });
    }
  };
}

const routes = Routes();
app.get('/', routes.Root);
app.listen(8080);
  • 你不必担心this的价值
  • 使用new调用函数无关紧要
  • 您可以避免在每条路线上调用bind的复杂性

有一个很好的资源列表here,为什么ES6类不如它们看起来那么好。


3
投票

或者,如果您不喜欢为每个路由绑定上下文,您可以选择将其绑定到类的构造函数本身中的方法。

E.g:

constructor() {
   this.foo = 10;
   this.Root = this.Root.bind(this);
}

2
投票

上面的答案似乎有点复杂。看看我在这里做了什么:

class Routes {
  constructor(req, res, next) {
    this.req = req;
    this.res = res;
    this.next = next;
    this.foo = "BAR"
    // Add more data to this. here if you like
  }

  findAll (){
    const {data, res,} = this; // Or just reference the objects directly with 'this'
    // Call functions, do whaterver here...
    // Once you have the right data you can use the res obejct to pass it back down

    res.json ({foo: this.foo}); // Grabs the foo value from the constructor

  }
}

现在,在使用这个类时,您可以按照以下方式执行操作:

var express = require('express');
var router = express.Router();
var {Routes} = require('./Routes');

router.get('/foo', (req, res, next) => {
  new Routes(req, res, next).findAll();
});

我会分开这两个文件,所以你只需要将Routes类放入你的Router文件中。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.