Jak ustawić zmienną w programie app.jsi mieć ją dostępną we wszystkich trasach, przynajmniej w index.jspliku znajdującym się w trasach. przy użyciu ekspresowych ram inode.js
Obiekt app.locals ma właściwości, które są zmiennymi lokalnymi w aplikacji. W pliku trasy odwołaj się do niego z req.app.locals.
Ronnie Royston
Odpowiedzi:
65
Aby utworzyć zmienną globalną, po prostu zadeklaruj ją bez varsłowa kluczowego. (Ogólnie rzecz biorąc, nie jest to najlepsza praktyka, ale w niektórych przypadkach może być przydatna - po prostu bądź ostrożny, ponieważ spowoduje to, że zmienna będzie dostępna wszędzie.)
//we can now access 'app' without redeclaring it or passing it in.../*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
Uwaga: generalnie lepiej jest wyraźnie mówić o przekazywaniu zmiennych i tworzeniu ich instancji, aby przypadkowo nie zerwać referencji w innym miejscu aplikacji lub co masz.
Paul,
3
To naprawdę zła forma, jak zauważył Paul. Proponuję poniższy wzór wtrysku. Tak, więcej kocowego kodu, więc nie wygląda "ładnie", ale zapewnia, że twój kod jest modułowy ... coś, co ci się spodoba, jeśli to nie jest twój ostatni projekt;)
srquinn
To zależy od okoliczności IMHO. Tak, globalne zmienne generalnie nie są dobrą praktyką (jak powiedziałem w mojej odpowiedzi) i zaczynając od zera, powiedziałbym, że zorganizuj wszystko w oddzielne moduły. Ale jeśli integrujesz się z istniejącym kodem, często istnieją inne kwestie - tak się składa, że jest to jedno (łatwe, ale niebezpieczne) rozwiązanie.
Jesse Fulton,
2
Czy ktoś mógłby wyjaśnić, dlaczego to działa w odniesieniu do semantyki Javascript? Z którym zakresem jest apppowiązany?
Ali
Nie sądzę, aby ta odpowiedź oznaczała jako correctjedną.
Code Cooker
93
W rzeczywistości jest to bardzo łatwe przy użyciu metod „set” i „get” dostępnych w obiekcie ekspresowym.
Przykład poniżej, powiedzmy, że masz zmienną o nazwie config z elementami związanymi z konfiguracją, które chcesz, aby były dostępne w innych miejscach:
Ustawić „aplikację” jako globalną? Tak. Ale ta metoda jest najlepsza, aby uchronić nas przed problemami i chaosem.
diproart
53
dla spóźnialskich: app.configure zostanie usunięta w express 4.x
zamil
Fajnie, req.app.get('name')działa jak urok. Ta właściwość zawiera odwołanie do wystąpienia aplikacji Express, która używa oprogramowania pośredniego. expressjs.com/pt-br/api.html#req.app
Lazaro Fernandes Lima Suleiman
58
Sprytnym sposobem na to jest użycie app.localssamego Expressu.
Oto dokumentacja.
// In app.js:
app.locals.variable_you_need = 42;
// In index.jsexports.route = function(req, res){
var variable_i_needed = req.app.locals.variable_you_need;
}
Użyłem tej metody do zlokalizowania usług http i łatwego nadpisywania w testach jednostkowych.
Alex
28
Aby zadeklarować zmienną globalną, musisz użyć obiektu globalnego . Na przykład global.yourVariableName. Ale to nie jest prawdziwa droga. Aby udostępniać zmienne między modułami, spróbuj użyć stylu wtrysku, takiego jak
Więc pracujesz z zestawem modułów Node, być może frameworkiem takim jak Express.js, i nagle czujesz potrzebę uczynienia niektórych zmiennych globalnymi. Jak sprawić, by zmienne były globalne w Node.js?
Najczęstszą radą w tym przypadku jest „zadeklarowanie zmiennej bez słowa kluczowego var”, „dodanie zmiennej do obiektu globalnego” lub „dodanie zmiennej do obiektu GLOBAL”. Którego używasz?
Po pierwsze, przeanalizujmy obiekt globalny. Otwórz terminal, uruchom Node REPL (zachęta).
W Expressie - gdy używasz jshint lub ogólnie lintingu - staje się to problemem.
Steven Ventimiglia
5
Było to pomocne pytanie, ale mogłoby być bardziej przydatne, podając rzeczywiste przykłady kodu. Nawet linkowany artykuł w rzeczywistości nie pokazuje implementacji. Dlatego pokornie poddaję:
W app.jspliku początek pliku:
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 nie będzie mieć żadnego odniesienia do app.get()metody. Pozostaw to do zdefiniowania w poszczególnych plikach tras.
routes/index.js:
require('./main');
require('./users');
i na koniec rzeczywisty plik tras routes/main.js:
functionindex (request, response) {
response.render('index', { title: 'Express' });
}
app.get('/',index); // <-- define the routes here now, thanks to the global app variable
Moim preferowanym sposobem jest użycie zależności cyklicznych *, które obsługuje węzeł
w app.js zdefiniuj var app = module.exports = express();jako pierwsze zamówienie biznesowe
Teraz każdy moduł wymagany po fakcie może var app = require('./app')uzyskać do niego dostęp
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 independentlyrequire('./user');
require('./blog');
Świetna wskazówka. Po prostu przeszedłem od metody require ('./ myroutes') (aplikacja) do zrobienia tego i uderzyłem głową o ścianę przez 10 minut, próbując dowiedzieć się, dlaczego żadna z moich tras nie zadziałała. Nie zapomnij pobrać specyfikacji tras w myroutes.js z bloku funkcyjnego. No!
greg
2
Jak inni już udostępnili, app.set('config', config)jest do tego świetny. Chciałem tylko dodać coś, czego nie widziałem w istniejących odpowiedziach, co jest dość ważne. Instancja Node.js jest współużytkowana we wszystkich żądaniach, więc chociaż może być bardzo praktyczne udostępnianie części configlub routerobiektów globalnie, globalne przechowywanie danych wykonawczych będzie dostępne dla żądań i użytkowników . Rozważmy ten bardzo prosty przykład:
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 functionvar foo = function() {
res.send(app.get('message'));
};
setTimeout(foo, 1000);
});
app.listen(3000);
Jeśli odwiedzisz stronę /bari trafi kolejna prośba /foo, Twoja wiadomość będzie brzmiała „Witamy w foo!”. To głupi przykład, ale trafia w sedno.
Rozwiązałem ten sam problem, ale musiałem napisać więcej kodu. Stworzyłem server.jsplik, który używa express do rejestracji tras. Udostępnia funkcję, registerktóra może być używana przez inne moduły do rejestrowania własnych tras. Udostępnia również funkcję startServer, aby rozpocząć nasłuchiwanie portu
Odpowiedź Johna Gordona była pierwszą z kilkudziesięciu częściowo wyjaśnionych / udokumentowanych odpowiedzi, które wypróbowałem, z wielu, wielu witryn, które faktycznie zadziałały. Dziękuję panie Gordon. Przepraszam, że nie mam punktów, aby poprawić Twoją odpowiedź.
Chciałbym dodać, że dla innych początkujących użytkowników dzielenia węzłów trasy-plików, użycie funkcji anonimowej dla `` indeksu '' jest tym, co będzie częściej widziane, więc używając przykładu Johna dla main.js, funkcjonalnie- równoważny kod, który normalnie można znaleźć, to:
jest to całkiem prosta rzecz, ale odpowiedzi ludzi są jednocześnie zagmatwane i złożone.
pokażę ci, jak możesz ustawić zmienną globalną w swojej expressaplikacji. W razie potrzeby możesz uzyskać do niego dostęp z dowolnej trasy.
Powiedzmy, że chcesz ustawić zmienną globalną z głównej /trasy
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
Będziesz więc otrzymywać wymaganą aplikację ze wszystkich tras. a następnie będziesz musiał użyć, localsaby ustawić dane globalne w. jak powyżej, pokaż, że wszystko gotowe teraz
pokażę ci, jak korzystać z tych danych
req.app.locals
.Odpowiedzi:
Aby utworzyć zmienną globalną, po prostu zadeklaruj ją bez
var
słowa kluczowego. (Ogólnie rzecz biorąc, nie jest to najlepsza praktyka, ale w niektórych przypadkach może być przydatna - po prostu bądź ostrożny, ponieważ spowoduje to, że zmienna będzie dostępna wszędzie.)Oto przykład z aplikacji visionmedia / screenshot
plik app.js :
/** * Module dependencies. */ var express = require('express') , stylus = require('stylus') , redis = require('redis') , http = require('http'); app = express(); //... require() route files
file route / 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'); }); //...
źródło
app
powiązany?correct
jedną.W rzeczywistości jest to bardzo łatwe przy użyciu metod „set” i „get” dostępnych w obiekcie ekspresowym.
Przykład poniżej, powiedzmy, że masz zmienną o nazwie config z elementami związanymi z konfiguracją, które chcesz, aby były dostępne w innych miejscach:
W app.js:
var config = require('./config'); app.configure(function() { ... app.set('config', config); ... }
W route / index.js
exports.index = function(req, res){ var config = req.app.get('config'); // config is now available ... }
źródło
req.app.get('name')
działa jak urok. Ta właściwość zawiera odwołanie do wystąpienia aplikacji Express, która używa oprogramowania pośredniego. expressjs.com/pt-br/api.html#req.appSprytnym sposobem na to jest użycie
app.locals
samego Expressu. Oto dokumentacja.// 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; }
źródło
Aby zadeklarować zmienną globalną, musisz użyć obiektu globalnego . Na przykład global.yourVariableName. Ale to nie jest prawdziwa droga. Aby udostępniać zmienne między modułami, spróbuj użyć stylu wtrysku, takiego jak
someModule.js:
module.exports = function(injectedVariable) { return { somePublicMethod: function() { }, anotherPublicMethod: function() { }, }; };
app.js
var someModule = require('./someModule')(someSharedVariable);
Lub możesz do tego użyć obiektu zastępczego. Jak hub .
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');
źródło
Oto krótkie wyjaśnienie:
http://www.hacksparrow.com/global-variables-in-node-js.html
Więc pracujesz z zestawem modułów Node, być może frameworkiem takim jak Express.js, i nagle czujesz potrzebę uczynienia niektórych zmiennych globalnymi. Jak sprawić, by zmienne były globalne w Node.js?
Najczęstszą radą w tym przypadku jest „zadeklarowanie zmiennej bez słowa kluczowego var”, „dodanie zmiennej do obiektu globalnego” lub „dodanie zmiennej do obiektu GLOBAL”. Którego używasz?
Po pierwsze, przeanalizujmy obiekt globalny. Otwórz terminal, uruchom Node REPL (zachęta).
> 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'
źródło
Najłatwiejszym sposobem jest wczesne zadeklarowanie zmiennej globalnej w pliku app.js:
global.mySpecialVariable = "something"
wtedy na dowolnych trasach możesz to zdobyć:
console.log(mySpecialVariable)
źródło
Było to pomocne pytanie, ale mogłoby być bardziej przydatne, podając rzeczywiste przykłady kodu. Nawet linkowany artykuł w rzeczywistości nie pokazuje implementacji. Dlatego pokornie poddaję:
W
app.js
pliku początek pliku: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 nie będzie mieć żadnego odniesienia do
app.get()
metody. Pozostaw to do zdefiniowania w poszczególnych plikach tras.routes/index.js
:require('./main'); require('./users');
i na koniec rzeczywisty plik tras
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
źródło
Moim preferowanym sposobem jest użycie zależności cyklicznych *, które obsługuje węzeł
var app = module.exports = express();
jako pierwsze zamówienie biznesowevar app = require('./app')
uzyskać do niego dostępapp.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');
źródło
Jak inni już udostępnili,
app.set('config', config)
jest do tego świetny. Chciałem tylko dodać coś, czego nie widziałem w istniejących odpowiedziach, co jest dość ważne. Instancja Node.js jest współużytkowana we wszystkich żądaniach, więc chociaż może być bardzo praktyczne udostępnianie częściconfig
lubrouter
obiektów globalnie, globalne przechowywanie danych wykonawczych będzie dostępne dla żądań i użytkowników . Rozważmy ten bardzo prosty przykład: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);
Jeśli odwiedzisz stronę
/bar
i trafi kolejna prośba/foo
, Twoja wiadomość będzie brzmiała „Witamy w foo!”. To głupi przykład, ale trafia w sedno.Jest kilka interesujących punktów na ten temat w Dlaczego różne sesje node.js współużytkują zmienne? .
źródło
Rozwiązałem ten sam problem, ale musiałem napisać więcej kodu. Stworzyłem
server.js
plik, który używa express do rejestracji tras. Udostępnia funkcję,register
która może być używana przez inne moduły do rejestrowania własnych tras. Udostępnia również funkcjęstartServer
, aby rozpocząć nasłuchiwanie portuserver.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 }
W innym module użyj tego pliku, aby utworzyć trasę.
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 }
W głównym pliku załaduj oba.
app.js require('./server').startServer(7000) require('./web/help').registerHelp()
źródło
Odpowiedź Johna Gordona była pierwszą z kilkudziesięciu częściowo wyjaśnionych / udokumentowanych odpowiedzi, które wypróbowałem, z wielu, wielu witryn, które faktycznie zadziałały. Dziękuję panie Gordon. Przepraszam, że nie mam punktów, aby poprawić Twoją odpowiedź.
Chciałbym dodać, że dla innych początkujących użytkowników dzielenia węzłów trasy-plików, użycie funkcji anonimowej dla `` indeksu '' jest tym, co będzie częściej widziane, więc używając przykładu Johna dla main.js, funkcjonalnie- równoważny kod, który normalnie można znaleźć, to:
app.get('/',(req, res) { res.render('index', { title: 'Express' }); });
źródło
Użyłem app.all
W moim przypadku używam confit do zarządzania konfiguracją,
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(); }); });
Na trasach po prostu to robisz
req.app.get('config').get('cookie');
źródło
jest to całkiem prosta rzecz, ale odpowiedzi ludzi są jednocześnie zagmatwane i złożone.
pokażę ci, jak możesz ustawić zmienną globalną w swojej
express
aplikacji. W razie potrzeby możesz uzyskać do niego dostęp z dowolnej trasy.Powiedzmy, że chcesz ustawić zmienną globalną z głównej
/
trasyrouter.get('/', (req, res, next) => { req.app.locals.somethingNew = "Hi setting new global var"; });
Będziesz więc otrzymywać wymaganą aplikację ze wszystkich tras. a następnie będziesz musiał użyć,
locals
aby ustawić dane globalne w. jak powyżej, pokaż, że wszystko gotowe teraz pokażę ci, jak korzystać z tych danychrouter.get('/register', (req, res, next) => { console.log(req.app.locals.somethingNew); });
Podobnie jak powyżej z
register
trasy, do której uzyskujesz dostęp, dane zostały ustawione wcześniej.W ten sposób możesz sprawić, by to działało!
źródło