112

ルートを別のファイルに分割したいのですが、1つのファイルにはすべてのルートが含まれ、もう1つのファイルには対応するアクションが含まれています。現在、これを実現するためのソリューションがありますが、アクションでアプリインスタンスにアクセスできるようにするには、アプリインスタンスをグローバルにする必要があります。私の現在の設定は次のようになります。

app.js:

var express   = require('express');
var app       = express.createServer();
var routes    = require('./routes');

var controllers = require('./controllers');
routes.setup(app, controllers);

app.listen(3000, function() {
  console.log('Application is listening on port 3000');
});

ルート.js:

exports.setup = function(app, controllers) {

  app.get('/', controllers.index);
  app.get('/posts', controllers.posts.index);
  app.get('/posts/:post', controllers.posts.show);
  // etc.

};

controllers / index.js:

exports.posts = require('./posts');

exports.index = function(req, res) {
  // code
};

コントローラ/posts.js:

exports.index = function(req, res) {
  // code
};

exports.show = function(req, res) {
  // code
};

ただし、この設定には大きな問題があります。アクション(controllers / *。js)に渡す必要のあるデータベースインスタンスとアプリインスタンスがあります。私が考えることができる唯一のオプションは、両方の変数をグローバルにすることですが、これは実際には解決策ではありません。ルートがたくさんあり、それらを中央に配置したいので、ルートをアクションから分離したいと思います。

アクションに変数を渡すが、ルートからアクションを分離するための最良の方法は何ですか?

4

8 に答える 8

175

を使用req.appして、req.app.get('somekey')

呼び出しによって作成されたアプリケーション変数express()は、要求オブジェクトと応答オブジェクトに設定されます。

参照:https ://github.com/visionmedia/express/blob/76147c78a15904d4e4e469095a29d1bec9775ab6/lib/express.js#L34-L35

于 2013-02-22T06:13:56.250 に答える
105

Node.jsは循環依存関係をサポートしています。
require('./ routers')(app)の代わりに循環依存関係を利用すると、多くのコードがクリーンアップされ、各モジュールがロードファイルへの相互依存性が低くなります。


app.js

var app = module.exports = express(); //now app.js can be required to bring app into any file

//some app/middleware setup, etc, including 
app.use(app.router);

require('./routes'); //module.exports must be defined before this line


ルート/index.js

var app = require('../app');

app.get('/', function(req, res, next) {
  res.render('index');
});

//require in some other route files...each of which requires app independently
require('./user');
require('./blog');


----2014年4月の更新-----
Express4.0は、express.router()メソッドを追加することにより、ルートを定義するためのユースケースを修正しました。
ドキュメント-http://expressjs.com/4x/api.html#router

新しいジェネレーターの例:
ルートの記述:
https
://github.com/expressjs/generator/blob/master/templates/js/routes/index.jsアプリへの追加/名前空間: https ://github.com /expressjs/generator/blob/master/templates/js/app.js#L24

他のリソースからアプリにアクセスするためのユースケースはまだあるため、循環依存関係は依然として有効なソリューションです。

于 2014-01-13T23:38:29.400 に答える
26

コメントで述べたように、関数をmodule.exportsとして使用できます。関数もオブジェクトであるため、構文を変更する必要はありません。

app.js

var controllers = require('./controllers')({app: app});

controllers.js

module.exports = function(params)
{
    return require('controllers/index')(params);
}

controllers / index.js

function controllers(params)
{
  var app = params.app;

  controllers.posts = require('./posts');

  controllers.index = function(req, res) {
    // code
  };
}

module.exports = controllers;
于 2012-04-10T15:57:39.680 に答える
6

または単にそれを行います:

var app = req.app

これらのルートに使用しているミドルウェア内。そのように:

router.use( (req,res,next) => {
    app = req.app;
    next();
});
于 2017-06-07T14:30:07.950 に答える
0

「contollers」という名前のフォルダがあるとします。

app.jsに次のコードを入れることができます:

console.log("Loading controllers....");
var controllers = {};

var controllers_path = process.cwd() + '/controllers'

fs.readdirSync(controllers_path).forEach(function (file) {
    if (file.indexOf('.js') != -1) {
        controllers[file.split('.')[0]] = require(controllers_path + '/' + file)
    }
});

console.log("Controllers loaded..............[ok]");

... と ...

router.get('/ping', controllers.ping.pinging);

コントローラforlderには、次のコードを含むファイル「ping.js」があります。

exports.pinging = function(req, res, next){
    console.log("ping ...");
}

そして、これはそれです...。

于 2015-06-26T10:07:38.860 に答える
0
  1. dbオブジェクトをどこにでも渡さずにすべてのコントローラーからアクセスできるようにするには、dbオブジェクトをすべてのreqオブジェクトにアタッチするアプリケーションレベルのミドルウェアを作成し、すべてのコントローラー内でアクセスできるようにします。
// app.js
let db = ...;  // your db object initialized
const contextMiddleware = (req, res, next) => {
  req.db=db;
  next();
};
app.use(contextMiddleware);
  1. どこにでもアプリインスタンスを渡さないようにするには、代わりに、アプリがある場所にルートを渡します
// routes.js  It's just a mapping.
exports.routes = [
  ['/', controllers.index],
  ['/posts', controllers.posts.index],
  ['/posts/:post', controllers.posts.show]
];

// app.js
var { routes }    = require('./routes');
routes.forEach(route => app.get(...route));
// You can customize this according to your own needs, like adding post request

最終的なapp.js:

// app.js
var express   = require('express');
var app       = express.createServer();

let db = ...;  // your db object initialized
const contextMiddleware = (req, res, next) => {
  req.db=db;
  next();
};
app.use(contextMiddleware);

var { routes }    = require('./routes');
routes.forEach(route => app.get(...route));

app.listen(3000, function() {
  console.log('Application is listening on port 3000');
});

別のバージョン:POSTリクエストを追加するなど、自分のニーズに応じてこれをカスタマイズできます

// routes.js  It's just a mapping.
let get = ({path, callback}) => ({app})=>{
  app.get(path, callback);
}
let post = ({path, callback}) => ({app})=>{
  app.post(path, callback);
}
let someFn = ({path, callback}) => ({app})=>{
  // ...custom logic
  app.get(path, callback);
}
exports.routes = [
  get({path: '/', callback: controllers.index}),
  post({path: '/posts', callback: controllers.posts.index}),
  someFn({path: '/posts/:post', callback: controllers.posts.show}),
];

// app.js
var { routes }    = require('./routes');
routes.forEach(route => route({app}));
于 2020-03-04T14:39:56.107 に答える
0

アプリインスタンスをNode-Typescriptで他の人に渡したい場合:

オプション1:(importインポート) の助けを借りて

//routes.ts
import { Application } from "express";
import { categoryRoute } from './routes/admin/category.route'
import { courseRoute } from './routes/admin/course.route';

const routing = (app: Application) => {
    app.use('/api/admin/category', categoryRoute)
    app.use('/api/admin/course', courseRoute)
}
export { routing }

次に、それをインポートしてアプリを渡します。

import express, { Application } from 'express';

const app: Application = express();
import('./routes').then(m => m.routing(app))

オプション2:の助けを借りてclass

// index.ts
import express, { Application } from 'express';
import { Routes } from './routes';


const app: Application = express();
const rotues = new Routes(app)
...

ここでは、Routesクラスのコンストラクターでアプリにアクセスします

// routes.ts
import { Application } from 'express'
import { categoryRoute } from '../routes/admin/category.route'
import { courseRoute } from '../routes/admin/course.route';

class Routes {
    constructor(private app: Application) {
        this.apply();
    }

    private apply(): void {
       this.app.use('/api/admin/category', categoryRoute)
       this.app.use('/api/admin/course', courseRoute)
    }
}

export { Routes }
于 2020-09-02T18:41:58.533 に答える
-1

データベースの場合、すべてのDB作業を単純なAPIで実行し、共有状態を回避するデータアクセスサービスを分離します。

ルートの分離.setupはオーバーヘッドのように見えます。代わりに、構成ベースのルーティングを配置したいと思います。そして、.jsonまたは注釈を使用してルートを構成します。

于 2012-04-10T15:19:56.350 に答える