App.js'deki Global Değişken rotalarda erişilebilir mi?


91

Bir değişkeni nasıl ayarlayabilirim app.jsve en azından index.jsrotalarda bulunan dosyada tüm rotalarda kullanılabilir olmasını nasıl sağlayabilirim ? ekspres çerçeveyi kullanarak venode.js


1
App.locals nesne uygulama içinde yerel değişkenler olan özelliklere sahiptir. Rota dosyanızda ile referans verin req.app.locals.
Ronnie Royston

Yanıtlar:


66

Global bir değişken oluşturmak için, onu varanahtar kelime olmadan bildirmeniz yeterlidir. (Genel olarak konuşursak, bu en iyi uygulama değildir, ancak bazı durumlarda faydalı olabilir - değişkeni her yerde kullanılabilir hale getireceği için dikkatli olun.)

İşte visionmedia / screenshot-app'den bir örnek

app.js dosyası :

/**
 * Module dependencies.
 */

var express = require('express')
  , stylus = require('stylus')
  , redis = require('redis')
  , http = require('http');

app = express();

//... require() route files

dosya yolları / main.js

//we can now access 'app' without redeclaring it or passing it in...

/*
 * GET home page.
 */

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

//...

6
Bir not olarak, değişkenleri etrafta dolaştırma ve onları örnekleme konusunda açık olmak genellikle daha iyidir, böylece uygulamada başka bir yerde ref'i yanlışlıkla sıfırlamazsınız veya neye sahip olursunuz.
Paul

3
Paul'un belirttiği gibi, bu gerçekten kötü bir biçim. Aşağıda belirtilen enjeksiyon modelini öneririm. Evet, daha fazla kazan plakası kodu, böylece "güzel" görünmüyor, ancak kodunuzun modüler olmasını sağlıyor ... bu son projeniz değilse beğeneceğiniz bir şey;)
srquinn

IMHO şartlarına bağlıdır. Evet, küresel değişkenler genellikle iyi bir uygulama değildir (cevabımda belirttiğim gibi) ve sıfırdan başlarken, her şeyi ayrı modüller halinde organize et derim. Ancak mevcut kodla entegre ediyorsanız, genellikle başka hususlar da vardır - bu sadece bir (kolay, ancak tehlikeli) çözüm olur.
Jesse Fulton 13

2
Birisi bunun neden Javascript'in anlambilimine referansla işe yaradığını açıklayabilir mi? Hangi kapsam ile appilişkilendirilir?
Ali

Bu cevabın correcttek olarak işaretlenmesi gerektiğini sanmıyorum .
Code Cooker

93

Bunu ekspres nesnede bulunan "set" ve "get" yöntemlerini kullanarak yapmak aslında çok kolaydır.

Aşağıdaki gibi bir örnek, başka yerlerde olmasını istediğiniz konfigürasyonla ilgili öğelerinizle birlikte config adlı bir değişkeniniz olduğunu varsayalım:

App.js'de:

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

app.configure(function() {
  ...
  app.set('config', config); 
  ...
}

Rotalarda / index.js'de

exports.index = function(req, res){
  var config = req.app.get('config');
  // config is now available
  ...
}

"Uygulama" global olarak ayarlansın mı? Evet. Ancak bu yöntem bizi sorunlardan ve kaostan kurtarmak için en iyisidir.
diproart

53
geç gelenler için: app.configure ekspres 4.x'te kaldırıldı
zamil

Güzel, req.app.get('name')bir cazibe gibi çalışıyor. Bu özellik, ara yazılımı kullanan Express uygulamasının örneğine bir başvuru içerir. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman

58

Bunu yapmanın düzgün bir yolu, app.localsExpress tarafından sağlanan kullanımıdır . İşte belgeler.

// In app.js:
app.locals.variable_you_need = 42;

// In index.js
exports.route = function(req, res){
    var variable_i_needed = req.app.locals.variable_you_need;
}

1
Bu yöntemi http hizmetlerini bulmak ve birim testlerinde kolayca geçersiz kılmak için kullandım.
Alex

28

Global bir değişkeni bildirmek için global nesneyi kullanmanız gerekir . Global.yourVariableName gibi. Ama bu doğru bir yol değil. Değişkenleri modüller arasında paylaşmak için enjeksiyon stilini kullanmayı deneyin.

someModule.js:

module.exports = function(injectedVariable) {
    return {
        somePublicMethod: function() {
        },
        anotherPublicMethod: function() {
        },
    };
};

app.js

var someModule = require('./someModule')(someSharedVariable);

Ya da bunu yapmak için vekil nesne kullanabilirsiniz. Gibi göbek .

someModule.js:

var hub = require('hub');

module.somePublicMethod = function() {
    // We can use hub.db here
};

module.anotherPublicMethod = function() {
};

app.js

var hub = require('hub');
hub.db = dbConnection;
var someModule = require('./someModule');

7

İşte kısaca iyi açıklayın:

http://www.hacksparrow.com/global-variables-in-node-js.html

Yani bir dizi Node modülüyle, belki Express.js gibi bir çerçeveyle çalışıyorsunuz ve aniden bazı değişkenleri global hale getirme ihtiyacını hissediyorsunuz. Node.js'de değişkenleri nasıl global yaparsınız?

Bunun için en yaygın tavsiye, "değişkeni var anahtar sözcüğü olmadan bildirmek" veya "değişkeni global nesneye eklemek" veya "değişkeni GLOBAL nesnesine eklemek" dir. Hangisini kullanıyorsun?

Öncelikle global nesneyi inceleyelim. Bir terminal açın, bir Düğüm REPL (komut istemi) başlatın.

> global.name
undefined
> global.name = 'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> delete global.name
true
> GLOBAL.name
undefined
> name = 'El Capitan'
'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> var name = 'Sparrow'
undefined
> global.name
'Sparrow'

Express'te - genel olarak jshint veya linting kullanırken - bu bir sorun haline gelir.
Steven Ventimiglia

6

en kolay yol, erken dönemde app.js'nizde global bir değişken bildirmektir:

global.mySpecialVariable = "something"

daha sonra herhangi bir rotada alabilirsiniz:

console.log(mySpecialVariable)

1
Express'te - jshint veya linting kullanılırken, genel olarak - bu bir sorun haline gelir.
Steven Ventimiglia

5

Bu yararlı bir soruydu, ancak gerçek kod örnekleri vererek daha da zor olabilirdi. Bağlantılı makale bile aslında bir uygulama göstermiyor. Bu nedenle, alçakgönüllülükle sunuyorum:

Senin içinde app.jsdosyanın, dosyanın üst:

var express = require('express')
, http = require('http')
, path = require('path');

app = express(); //IMPORTANT!  define the global app variable prior to requiring routes!

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

app.js, yönteme herhangi bir referans içermez app.get(). Bunları ayrı yol dosyalarında tanımlanmaya bırakın.

routes/index.js:

require('./main');
require('./users');

ve son olarak, gerçek bir rota dosyası routes/main.js:

function index (request, response) {
    response.render('index', { title: 'Express' });
}

app.get('/',index); // <-- define the routes here now, thanks to the global app variable

4

Tercih ettiğim yöntem, düğümün desteklediği döngüsel bağımlılıkları * kullanmaktır

  • app.js'de var app = module.exports = express();ilk iş siparişiniz olarak tanımlayın
  • Artık var app = require('./app')erişebilmek için gerekli olan herhangi bir modül


app.js

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

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

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


route / 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');

Harika bir ipucu. Bunu yapmak için require ('./ myroutes') (app) yönteminden yeni geçtim ve rotalarımdan hiçbirinin neden işe yaramadığını anlamaya çalışırken 10 dakika boyunca kafamı duvara çarptım. Myroutes.js'de bir fonksiyon bloğundan rota spesifikasyonlarını almayı unutmayın. Doh!
greg

2

Başkalarının zaten paylaştığı gibi, app.set('config', config)bunun için harika. Sadece mevcut cevaplarda görmediğim oldukça önemli bir şey eklemek istedim. Bir Node.js örneği tüm isteklerde paylaşılır, bu nedenle bazılarının configveya routernesnelerin küresel olarak paylaşılması çok pratik olsa da , çalışma zamanı verilerinin küresel olarak depolanması istekler ve kullanıcılar arasında kullanılabilir olacaktır . Şu çok basit örneği düşünün:

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

app.get('/foo', function(req, res) {
    app.set('message', "Welcome to foo!");
    res.send(app.get('message'));
});

app.get('/bar', function(req, res) {
    app.set('message', "Welcome to bar!");

    // some long running async function
    var foo = function() {
        res.send(app.get('message'));
    };
    setTimeout(foo, 1000);
});

app.listen(3000);

Ziyaret ederseniz /barve başka bir istek isabet ederse /foo, mesajınız "Foo'ya hoş geldiniz!" Olacaktır. Bu aptalca bir örnek, ama asıl noktayı anlıyor.

Bununla ilgili bazı ilginç noktalar var: Neden farklı node.js oturumları değişkenleri paylaşıyor? .


1

Aynı sorunu çözdüm ama daha fazla kod yazmam gerekiyordu. server.jsYolları kaydetmek için ekspres kullanan bir dosya oluşturdum . registerDiğer modüller tarafından kendi rotalarını kaydetmek için kullanılabilecek bir işlevi ortaya çıkarır . Ayrıca startServerbir bağlantı noktasını dinlemeye başlamak için bir işlevi de ortaya çıkarır.

server.js

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

const register = (path,method,callback) => methodCalled(path, method, callback)

const methodCalled = (path, method, cb) => {
  switch (method) {
    case 'get':
      app.get(path, (req, res) => cb(req, res))
      break;
    ...
    ...  
    default:
      console.log("there has been an error");
  }
}

const startServer = (port) => app.listen(port, () => {console.log(`successfully started at ${port}`)})

module.exports = {
  register,
  startServer
}

Başka bir modülde, bir rota oluşturmak için bu dosyayı kullanın.

help.js

const app = require('../server');

const registerHelp = () => {
  app.register('/help','get',(req, res) => {
    res.send("This is the help section")
  }),
  app.register('/help','post',(req, res) => {
    res.send("This is the help section")
  })}

module.exports = {
  registerHelp
}

Ana dosyada, her ikisini de önyükleyin.

app.js

require('./server').startServer(7000)
require('./web/help').registerHelp()

1

bu oldukça kolay bir şey, ancak insanların cevapları aynı zamanda kafa karıştırıcı ve karmaşık.

expressuygulamanızda global değişkeni nasıl ayarlayabileceğinizi size göstereyim . Böylece ona herhangi bir rotadan gerektiği gibi erişebilirsiniz.

Diyelim ki ana /rotanızdan global bir değişken ayarlamak istiyorsunuz

router.get('/', (req, res, next) => {

  req.app.locals.somethingNew = "Hi setting new global var";
});

Böylece tüm rotalardan req.app alacaksınız. ve ardından localsglobal verileri içine ayarlamak için kullanmanız gerekecek . Yukarıdaki şov gibi, hepiniz hazırsınız. şimdi size bu verileri nasıl kullanacağınızı göstereceğim

router.get('/register', (req, res, next) => {

  console.log(req.app.locals.somethingNew);
});

registerVerilere eriştiğiniz rotadan yukarıdaki gibi daha önce ayarlanmış.

Bu şeyi bu şekilde çalıştırabilirsiniz!


0

John Gordon'un cevabı, pek çok siteden denediğim, gerçekten işe yarayan düzinelerce yarı açıklanmış / belgelenmiş cevaptan ilkiydi. Teşekkürler Bay Gordon. Maalesef cevabınızı yükseltecek puanım yok.

Düğüm-yol-dosya-bölmeye yeni başlayanlar için, 'dizin' için anonim işlevin kullanımının daha sık göreceğini, bu nedenle John'un main.js örneğini kullanarak, işlevsel olarak- normalde bulacağınız eşdeğer kod:

app.get('/',(req, res) {
    res.render('index', { title: 'Express' });
});

0

App.all kullandım

App.all () yöntemi, belirli yol önekleri veya rastgele eşleşmeler için "global" mantığı eşlemek için kullanışlıdır.

Benim durumumda, konfigürasyon yönetimi için confit kullanıyorum ,

app.all('*', function (req, res, next) {
    confit(basedir).create(function (err, config) {
        if (err) {
            throw new Error('Failed to load configuration ', err);
        }
        app.set('config', config);
        next();
    });
});

Rotalarda yaparsın req.app.get('config').get('cookie');

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.