एक्सप्रेस / नोड.जेएस का उपयोग करते हुए सभी दृष्टिकोणों में सुलभ वैश्विक चर कैसे बनाएं?


81

ठीक है, इसलिए मैंने Jekyll का उपयोग करके एक ब्लॉग बनाया है और आप चर को किसी फ़ाइल में परिभाषित कर सकते हैं _config.ymlजो सभी टेम्प्लेट या लेआउट में सुलभ हैं। मैं वर्तमान में उपयोग कर रहा हूँ Node.js / एक्सप्रेस के साथ EJS टेम्पलेट्स और EJS-स्थानीय लोगों (partials / लेआउट के लिए। मैं वैश्विक चर की तरह के समान कुछ करने के लिए देख रहा हूँ site.titleकि में पाए जाते हैं _config.yml, तो किसी को भी Jekyll से परिचित है। मैं की तरह चर है साइट का शीर्षक, (पृष्ठ शीर्षक के बजाय), लेखक / कंपनी का नाम, जो मेरे सभी पृष्ठों पर समान रहते हैं।

यहाँ मैं वर्तमान में क्या कर रहा हूँ का एक उदाहरण है:

exports.index = function(req, res){
    res.render('index', { 
        siteTitle: 'My Website Title',
        pageTitle: 'The Root Splash Page',
        author: 'Cory Gross',
        description: 'My app description',
        indexSpecificData: someData
    });
};

exports.home = function (req, res) {
    res.render('home', {
        siteTitle: 'My Website Title',
        pageTitle: 'The Home Page',
        author: 'Cory Gross',
        description: 'My app description',
        homeSpecificData: someOtherData
    });
};

मैं एक स्थान पर मेरी साइट के शीर्षक, विवरण, लेखक आदि जैसे चर को परिभाषित करने में सक्षम होना चाहता हूं और उन्हें ईजेएस के माध्यम से मेरे लेआउट / टेम्पलेट में सुलभ होना चाहिए, उन्हें प्रत्येक कॉल के विकल्प के रूप में पारित करने के लिए बिना res.render। क्या ऐसा करने का कोई तरीका है और फिर भी मुझे प्रत्येक पृष्ठ के लिए विशिष्ट अन्य चर में पारित करने की अनुमति है?

जवाबों:


109

एक्सप्रेस 3 एपीआई संदर्भ का थोड़ा और अध्ययन करने का मौका मिलने के बाद मुझे पता चला कि मैं क्या देख रहा था। विशेष रूप से प्रविष्टियों के लिए app.localsऔर फिर थोड़ा और नीचे res.localsदिए गए उत्तरों की आवश्यकता थी।

मैंने अपने लिए खोजा कि फ़ंक्शन app.localsएक ऑब्जेक्ट लेता है और इसके सभी गुणों को संग्रहीत करता है, क्योंकि वैश्विक चर अनुप्रयोग के लिए स्कैन किए गए हैं। ये ग्लोबल्स प्रत्येक दृश्य के लिए स्थानीय चर के रूप में पारित किए जाते हैं। res.localsहालाँकि, फ़ंक्शन को अनुरोध के लिए बंद कर दिया गया है और इस प्रकार, प्रतिक्रिया स्थानीय चर केवल उस विशेष अनुरोध / प्रतिक्रिया के दौरान प्रस्तुत किए गए दृश्य (नों) तक पहुंच योग्य है।

मेरे मामले में मेरे मामले में मैंने app.jsजो किया, वह इस प्रकार था:

app.locals({
    site: {
        title: 'ExpressBootstrapEJS',
        description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.'
    },
    author: {
        name: 'Cory Gross',
        contact: 'CoryG89@gmail.com'
    }
});

तो फिर इन चरों के सभी के रूप में मेरे विचारों में जाया जा सकता है site.title, site.description, author.name, author.contact

मैं अनुरोध के साथ प्रत्येक प्रतिक्रिया के लिए स्थानीय चर भी परिभाषित कर सकता हूं res.locals, या केवल कॉल optionsमें पैरामीटर के रूप में पृष्ठ के शीर्षक जैसे चर पास कर सकता हूं render

EDIT: यह विधि आपको अपने मिडलवेयर में इन स्थानीय लोगों का उपयोग करने की अनुमति नहीं देगी। मैं वास्तव में इस में चला गया के रूप में Pickels नीचे टिप्पणी में पता चलता है। इस मामले में आपको उसके वैकल्पिक (और सराहना) उत्तर में एक मिडलवेयर फ़ंक्शन बनाने की आवश्यकता होगी। आपके मिडलवेयर फ़ंक्शन को उन्हें res.localsप्रत्येक प्रतिक्रिया के लिए जोड़ना होगा और फिर कॉल करना होगा next। इस मिडलवेयर फ़ंक्शन को किसी अन्य मिडलवेयर के ऊपर रखा जाना चाहिए, जिसे इन स्थानीय लोगों का उपयोग करने की आवश्यकता है।

संपादित करें: के माध्यम से स्थानीय लोगों की घोषणा बीच एक और अंतर app.localsऔर res.localsउस के साथ है app.localsचर एक ही समय निर्धारित किया है और आवेदन की जीवन भर जारी रहती है कर रहे हैं। जब आप स्थानीय लोगों को res.localsअपने मिडलवेयर के साथ सेट करते हैं, तो ये आपके द्वारा अनुरोध प्राप्त करने के लिए निर्धारित किए जाते हैं। आपको मूल रूप से ग्लोबल्स सेट करना पसंद करना चाहिए app.localsजब तक कि मूल्य reqमिडलवेयर में पारित अनुरोध चर पर निर्भर करता है । यदि मान नहीं बदलता है, तो इसे केवल एक बार सेट करने के लिए अधिक कुशल होगा app.locals


1
app.locals ने मेरे द्वारा सुझाए गए से अधिक समझ में आता है। यह एक पकड़ है, हालांकि, आप अपने मिडलवेयर में स्थानीय लोगों तक नहीं पहुंच सकते। इस मामले में यह शायद कोई फर्क नहीं पड़ता है, लेकिन यह उन गोचरों में से एक है जिन्हें आप कभी-कभी चलाते हैं।
पिकल्स

आप किसी js या json फ़ाइल में कॉन्फ़िगरेशन को भी परिभाषित कर सकते हैं और बस आपको इसकी आवश्यकता होती है। एप्लिकेशन के दौरान फ़ाइल केवल एक बार लोड होगी, और इसके लिए आवश्यक हर मॉड्यूल को उसके द्वारा निर्धारित मूल्यों तक पहुंच प्राप्त होगी। पर विभिन्न उत्तर देखें stackoverflow.com/questions/5869216/...
जो लैप

51
में एक्सप्रेस 4 locals एक समारोह है, लेकिन एक वस्तु नहीं है। एक संपत्ति सेट करने के लिए:app.locals.site.title = 'Example';
मार्टीन लाएन

वाह! अब पूरा ऐप एक सिंगल फाइल के जरिए कंफर्टेबल है। एक साफ शॉट। +1
दीपक

@MarttiLaine धन्यवाद दोस्त!
अली इमरे makmakoğlu 14

55

आप इसे सामान्य मिडलवेयर में स्थानीय ऑब्जेक्ट में जोड़कर कर सकते हैं।

app.use(function (req, res, next) {
   res.locals = {
     siteTitle: "My Website's Title",
     pageTitle: "The Home Page",
     author: "Cory Gross",
     description: "My app's description",
   };
   next();
});

लोकल भी एक ऐसा फंक्शन है जो लोकल ऑब्जेक्ट को ओवरराइट करने के बजाय बढ़ाएगा। तो निम्नलिखित भी काम करता है

res.locals({
  siteTitle: "My Website's Title",
  pageTitle: "The Home Page",
  author: "Cory Gross",
  description: "My app's description",
});

पूर्ण उदाहरण

var app = express();

var middleware = {

    render: function (view) {
        return function (req, res, next) {
            res.render(view);
        }
    },

    globalLocals: function (req, res, next) {
        res.locals({ 
            siteTitle: "My Website's Title",
            pageTitle: "The Root Splash Page",
            author: "Cory Gross",
            description: "My app's description",
        });
        next();
    },

    index: function (req, res, next) {
        res.locals({
            indexSpecificData: someData
        });
        next();
    }

};


app.use(middleware.globalLocals);
app.get('/', middleware.index, middleware.render('home'));
app.get('/products', middleware.products, middleware.render('products'));

मैंने एक जेनेरिक रेंडर मिडलवेयर भी जोड़ा। इस तरह से आपको प्रत्येक मार्ग पर res.render नहीं जोड़ना होगा जिसका अर्थ है कि आपके पास बेहतर कोड का उपयोग है। एक बार जब आप पुन: प्रयोज्य मिडलवेयर मार्ग पर जाते हैं, तो आप देखेंगे कि आपके पास बहुत से बिल्डिंग ब्लॉक होंगे जो विकास को बहुत तेजी से बढ़ाएंगे।


मुझे पता है कि यह एक पुराना उत्तर है, लेकिन आपके globalLocalsकार्य के लिए reqऔर resपीछे की ओर हैं।
ब्रैंडन 927

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

1
res.localsअब एक फ़ंक्शन नहीं लगता है।
किलोज

मैं पाद लेख में कुछ उत्पादों को दिखाने के लिए आपके दृष्टिकोण का उपयोग करता हूं। धन्यवाद!
कार्नारू वैलेंटाइन

18

एक्सप्रेस 4.0 के लिए मैंने पाया कि एप्लिकेशन स्तर चर का उपयोग करना थोड़ा अलग तरीके से काम करता है और Cory का जवाब मेरे लिए काम नहीं करता।

डॉक्स से: http://expressjs.com/en/api.html#app.locals

मैंने पाया कि आप ऐप के लिए एक वैश्विक चर घोषित कर सकते हैं

app.locals

जैसे

app.locals.baseUrl = "http://www.google.com"

और फिर अपने आवेदन में आप इन चरों को एक्सेस कर सकते हैं और अपने एक्सप्रेस मिडलवेयर में आप इन्हें पुनः ऑब्जेक्ट के रूप में एक्सेस कर सकते हैं

req.app.locals.baseUrl

जैसे

console.log(req.app.locals.baseUrl)
//prints out http://www.google.com

1
जब कोड में नए लोकल जोड़े जाते हैं तो भी एक्सप्रेस सर्वर को फिर से शुरू करने की आवश्यकता होती है।
Wtower

14

अपने app.js में आपको कुछ इस तरह से जोड़ने की जरूरत है

global.myvar = 100;

अब, आपकी सभी फ़ाइलों में आप इस चर का उपयोग करना चाहते हैं, आप इसे केवल इस रूप में एक्सेस कर सकते हैं myvar


मैं मॉड्यूल की आवश्यकता का उपयोग कर रहा हूं, और इसे global.myvarहर जगह के रूप में संदर्भित करना था , और यह काम किया। यह सॉकेट.आईओ के लिए एक अच्छा आसान समाधान था, जहां मैं अन्य फाइलों में हैंडलर से संदेशों का उत्सर्जन करना चाहता हूं। मैंने अपना "io" ऑब्जेक्ट डाल दिया global.myIOऔर सभी महान काम कर रहे हैं।
थॉमस पोर्टर

6
यह वास्तव में अनुशंसित नहीं है या नोड विकास में एक अच्छा अभ्यास माना जाता है। Node.JS में कॉमनजेएस प्रणाली पर आधारित एक मॉड्यूल प्रणाली कार्यान्वयन शामिल है और पूरी तरह से मॉड्यूल के विचार पर केंद्रित है जो वैश्विक गुंजाइश साझा नहीं करते हैं, इसके बजाय आवश्यकता पद्धति का उपयोग करते हैं। यह एक्सप्रेस के लिए स्थानीय के बजाय नोड में एक वैश्विक जेएस संस्करण भी निर्धारित करता है / प्रश्न जैसे प्रश्न के लिए टेम्पलेट।
कोरी ग्रॉस

@CoryGross क्या इस तरह से एक वैश्विक चर के रूप में अनुरोध ऑब्जेक्ट सेट करना एक अच्छा अभ्यास है?
अली शराफत

केवल इसी ने काम किया। धन्यवाद श्री एफ! @CoryGross मैं अपने एप्लिकेशन की सभी फ़ाइलों को किसी एक ऑब्जेक्ट तक कैसे पहुंचने दूं?
दिविज सहगल

यह सबसे अच्छा जवाब है। इसका मतलब यह है कि वैश्विक वस्तु एक दृश्य या कहीं भी आप चाहते हैं पास करने के लिए उपलब्ध है। जैसे global.cdnURL = "https://cdn.domain.comकि आप स्थैतिक शंकु को लोड करने के लिए दृश्य में पास कर सकते हैं।
वॉल्यूम एक

1

app.localsउस ऐप के लिए वैरिएबल को अपडेट करके ऐसा करने का एक तरीका हैapp.js

निम्नलिखित के माध्यम से सेट करें

var app = express();
app.locals.appName = "DRC on FHIR";

प्रवेश की अनुमति लेना

app.listen(3000, function () {
    console.log('[' + app.locals.appName + '] => app listening on port 3001!');
});

थोड़ी वृद्धि के साथ @RamRovi उदाहरण के स्क्रीनशॉट के साथ विस्तार।

यहाँ छवि विवरण दर्ज करें


1

आप "वैश्विक" का भी उपयोग कर सकते हैं

उदाहरण:

इस तरह घोषित करें:

  app.use(function(req,res,next){
      global.site_url = req.headers.host;   // hostname = 'localhost:8080'
      next();
   });

इस तरह का उपयोग करें: किसी भी विचार या ईजेएस फ़ाइल में <% कंसोल.लॉग (साइट_उर्ल); %>

js फ़ाइलों में कंसोल .log (site_url);


0

अलग-अलग उत्तरों के साथ, मैंने "app.locals" में भरी हुई एक बाहरी फ़ाइल JSON का उपयोग करने के लिए इस कोड को लागू किया

मापदंडों

{
    "web": {
        "title" : "Le titre de ma Page",
        "cssFile" : "20200608_1018.css"
    }
}

आवेदन

var express     = require('express');
var appli       = express();
var serveur     = require('http').Server(appli);

var myParams    = require('./include/my_params.json');
var myFonctions = require('./include/my_fonctions.js');

appli.locals = myParams;

ईजेएस पेज

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <title><%= web.title %></title>
    <link rel="stylesheet" type="text/css" href="/css/<%= web.cssFile %>">
</head>

</body>
</html>

इसकी उम्मीद करने से मदद मिलेगी


-1

प्रदूषित वैश्विक गुंजाइश से बचने के लिए मैं जो भी करता हूं वह एक ऐसी स्क्रिप्ट तैयार करना है जिसे मैं कहीं भी शामिल कर सकता हूं।

// my-script.js
const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime;
const config = require('../../config/config').actionsOverTime;
let aotInstance;

(function () {
  if (!aotInstance) {
    console.log('Create new aot instance');
    aotInstance = ActionsOverTime.createActionOverTimeEmitter(config);
  }
})();

exports = aotInstance;

ऐसा करने से केवल एक बार एक नया उदाहरण बनेगा और साझा किया जाएगा कि हर जगह जहां फ़ाइल शामिल है। मुझे यकीन नहीं है कि यह इसलिए है क्योंकि अनुप्रयोग के लिए एक आंतरिक संदर्भ तंत्र के कारण चर को कैश किया गया है या इसके कारण (जिसमें कैशिंग शामिल हो सकता है)। कैसे नोड हल करता है पर कोई टिप्पणी यह ​​बहुत अच्छा होगा।

शायद यह भी पढ़ें कि काम की आवश्यकता के बारे में जानकारी पाने के लिए: http://fredkschott.com/post/2014/06/require-and-the-module-system/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.