2012-04-10 6 views
86

मैं अपने मार्गों को अलग-अलग फ़ाइलों में विभाजित करना चाहता हूं, जहां एक फ़ाइल में सभी मार्ग होते हैं और दूसरा एक संबंधित क्रिया होता है। मेरे पास वर्तमान में इसे प्राप्त करने का एक समाधान है, हालांकि मुझे ऐप-इंस्टेंस ग्लोबल को क्रियाओं में पहुंचने में सक्षम होने की आवश्यकता है। मेरे मौजूदा सेटअप इस तरह दिखता है:एक्सप्रेस: ​​एक अलग फ़ाइल से मार्गों पर ऐप-इंस्टेंस कैसे पास करें?

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'); 
}); 

routes.js:

exports.setup = function(app, controllers) { 

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

}; 

नियंत्रकों/index.js:

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

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

नियंत्रकों/पदों .js:

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

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

हालांकि, इस सेटअप में एक बड़ा मुद्दा है: मेरे पास एक डेटाबेस है- और एक ऐप-इंस्टेंस मुझे क्रियाओं (नियंत्रकों/*। जेएस) को पास करने की आवश्यकता है। एकमात्र विकल्प जो मैं सोच सकता था, दोनों वैरिएबल ग्लोबल बना रहा है जो वास्तव में एक समाधान नहीं है। मैं कार्यों से मार्ग अलग करना चाहता हूं क्योंकि मेरे पास बहुत सारे मार्ग हैं और उन्हें केंद्रीय स्थान पर चाहते हैं।

कार्यों में चर पारित करने का सबसे अच्छा तरीका क्या है लेकिन मार्गों से कार्यों को अलग करें?

+0

आपके नियंत्रक.जेएस कैसा दिखता है? हो सकता है कि आप इसे एक फ़ंक्शन (ऑब्जेक्ट के बजाए) बना सकें जो पैरामीटर प्राप्त कर सके। – mihai

+0

की आवश्यकता है ('नियंत्रक') नियंत्रकों/index.js की आवश्यकता है। हालांकि, एक समारोह काम नहीं करेगा क्योंकि मैं मार्गों में ऑब्जेक्ट का उपयोग करता हूं (मार्ग.जेएस देखें) और इस प्रकार यह तर्क नहीं दे सकता है, भले ही यह एक कार्य है। –

उत्तर

81

Node.js परिपत्र निर्भरता का समर्थन करता है।
बजाय परिपत्र निर्भरता की आवश्यकता होती है ('./ मार्गों') (एप्लिकेशन) द मेकिंग उपयोग कोड का एक बहुत कुछ को साफ और उसके लोड हो रहा है फ़ाइल पर प्रत्येक मॉड्यूल कम अन्योन्याश्रित बनाता है:


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 


मार्ग/अनुक्रमणिका।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'); 


----- 04/2014 अद्यतन -----
एक्सप्रेस 4.0 तय एक express.router() विधि जोड़कर मार्गों को परिभाषित करने के लिए USECASE!
प्रलेखन - अपने नए जनरेटर से 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

अभी भी अन्य संसाधनों से एप्लिकेशन तक पहुंचने का usecases कर रहे हैं, इसलिए परिपत्र निर्भरता अभी भी एक वैध समाधान है।

+1

"इसकी लोडिंग फ़ाइल पर कम परस्पर निर्भर" - यह इसकी लोडिंग फ़ाइल के विशिष्ट * फ़ाइलपाथ * पर निर्भर है।यह बहुत तंग युग्मन है, तो आइए नाटक न करें कि यह नहीं है। –

+1

बस बहुत सावधान रहें (पढ़िए: जो मैं पिछले घंटे के लिए संघर्ष कर रहा हूं, वह न करें) कि 'app.js' में आपको ऐप को निर्यात करने के बाद रूटिंग फ़ाइल _after_ की आवश्यकता होती है। परिपत्र 'की आवश्यकता है() 'कॉल वास्तविक गड़बड़ी के लिए कर सकते हैं, इसलिए सुनिश्चित करें कि आप जानते हैं [वे कैसे काम करते हैं] (http://nodejs.org/docs/latest/api/modules.html#modules_cycles)! – Nateowami

+0

मैं ईमानदारी से सोचता हूं कि req.app.get ('somekey') का उपयोग करने के बारे में @Feng का जवाब वास्तव में परिसंचरण निर्भरताओं का उपयोग करने से बेहतर और क्लीनर समाधान है। –

0

डेटाबेस के लिए डेटा एक्सेस सेवा अलग करें जो सरल डीपी के साथ सभी डीबी काम करेगा और साझा राज्य से बचें।

अलग-अलग मार्ग.सेटअप ओवरहेड की तरह दिखता है। मैं इसके बजाय कॉन्फ़िगरेशन आधारित रूटिंग रखना पसंद करूंगा। और .json या एनोटेशन के साथ मार्गों को कॉन्फ़िगर करें।

+0

डेटा एक्सेस सेवा के साथ आपका क्या मतलब है? यह कैसा दिखता है? –

+0

मेरी असली मार्ग.जेएस फ़ाइल बहुत बड़ी है और एक्सप्रेस-नेमस्पेस मॉड्यूल का उपयोग करती है। आप मार्गों से मार्गों को कैसे अलग करेंगे? –

25

जैसा कि मैंने टिप्पणियों में कहा था, आप मॉड्यूल.एक्सपोर्ट्स के रूप में एक फ़ंक्शन का उपयोग कर सकते हैं। एक समारोह भी एक वस्तु है, इसलिए आपको अपना वाक्यविन्यास बदलने की ज़रूरत नहीं है।

app.js

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

controllers.js

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

नियंत्रकों/index.js

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

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

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

module.exports = controllers; 
+0

क्या फ़ंक्शन के अंदर किसी ऑब्जेक्ट को वापस करना ठीक है या यह बेहतर है ताकि आप अपने उदाहरण में तरीकों को सेट कर सकें? –

+0

मुझे लगता है कि या तो दृष्टिकोण ठीक है। – mihai

+0

क्योंकि मेरे पास बहुत सी विधियां हैं, इसलिए मैं उन्हें प्रत्येक मैन्युअल रूप से ऑब्जेक्ट के रूप में सेट करना पसंद करूंगा। यह तब काम करेगा जब मैं ऑब्जेक्ट वापस कर दूंगा, लेकिन क्या कोई समाधान नहीं है जो थोड़ी चापलूसी है? मेरी वास्तविक विधियों को दो बार इंडेंट किया जाएगा ... –

144

उपयोग req.app, req.app.get('somekey')

appli express() पर कॉल करके बनाया गया cation variable अनुरोध और प्रतिक्रिया ऑब्जेक्ट पर सेट है।

देखें: https://github.com/visionmedia/express/blob/76147c78a15904d4e4e469095a29d1bec9775ab6/lib/express.js#L34-L35

+0

धन्यवाद। मुझे लगता है कि यह app.set ('name', val) के साथ सेट चर का उपयोग करने का सबसे अच्छा तरीका है; –

+4

ऐप.जेएस में 'app.set (' somekey ', {})' को कॉल करना न भूलें – ankitjaininfo

+1

इस तरह के बारे में मेरा एकमात्र गड़बड़ हालांकि मुझे यह पसंद है कि जब आप कोई ऐप चलाने की कोशिश कर रहे हैं। Locals.authorized जैसे (main.js में नहीं): 'app.route ('/ something') प्राप्त करें (app.locals.authorized, function (req, res, next) {});' संभव नहीं है क्योंकि यह req के बाहर है गुंजाइश। – gabeio

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 ..."); 
} 

और यह यह है ....

2
: इस कोड के साथ

var app = req.app 

Middleware के अंदर आप इन मार्गों के लिए उपयोग कर रहे हैं:

या तो बस यही काम। इस तरह:

router.use((req,res,next) => { 
    app = req.app; 
    next(); 
}); 
संबंधित मुद्दे