AngularJS में वैश्विक चर


348

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

मुझे लगता है कि यह वैश्विक वैरिएबल्स को घोषित करने और शुरू करने का सही तरीका नहीं है, अच्छी तरह से वास्तव में वैश्विक नहीं है, इसलिए मेरा सवाल यह है कि सही तरीका क्या है और क्या कोणीय के वर्तमान संस्करण के साथ उस काम के आसपास कोई अच्छा उदाहरण है?


12
चूंकि यह # 1 Google परिणाम है: अब आप ऐप-वाइड कॉन्स्टेंट और चर बनाने के लिए app.constant () और app.value () का उपयोग कर सकते हैं। यहाँ और अधिक: bit.ly/1P51PED
Mroz

जवाबों:


491

आपको मूल रूप से "वैश्विक" चर के लिए 2 विकल्प मिले हैं:

$rootScopeसभी स्कोपों ​​का एक अभिभावक है, इसलिए वहाँ प्रदर्शित होने वाले मूल्य सभी टेम्प्लेट और नियंत्रक में दिखाई देंगे। का उपयोग करना $rootScopeबहुत आसान है क्योंकि आप इसे किसी भी नियंत्रक में इंजेक्ट कर सकते हैं और इस दायरे में मूल्यों को बदल सकते हैं। यह सुविधाजनक हो सकता है लेकिन वैश्विक चर की सभी समस्याएं हैं

सेवाएं एकल हैं जो आप किसी भी नियंत्रक को इंजेक्ट कर सकते हैं और एक नियंत्रक के दायरे में उनके मूल्यों को उजागर कर सकते हैं। सेवाएँ, एकल होने के नाते अभी भी 'वैश्विक' हैं, लेकिन जहाँ आप उपयोग किए जाते हैं और उजागर होते हैं, वहां आपने बेहतर नियंत्रण प्राप्त किया है।

सेवाओं का उपयोग करना थोड़ा अधिक जटिल है, लेकिन इतना नहीं, यहां एक उदाहरण है:

var myApp = angular.module('myApp',[]);
myApp.factory('UserService', function() {
  return {
      name : 'anonymous'
  };
});

और फिर एक नियंत्रक में:

function MyCtrl($scope, UserService) {
    $scope.name = UserService.name;
}

यहाँ काम कर रहा है jsFiddle: http://jsfiddle.net/pkozlowski_opensource/BRWPM/2/


141
से कोणीय पूछे जाने वाले प्रश्न : इसके विपरीत, एक सेवा जिसका केवल जीवन में उद्देश्य डेटा की दुकान और बदले बिट्स करने के लिए है न बनाएं।
जैकब स्टोक

7
मैं Btford द्वारा एक्सप्रेस + कोणीय बीज का उपयोग कर रहा हूं । अगर मैं कंट्रोलर 1 में $ rootScope पर एक वैरिएबल सेट करता हूं, तो दूसरे url पर जाएं (कंट्रोलर 2 द्वारा संचालित) मैं इस वेरिएबल को एक्सेस कर सकता हूं। हालाँकि यदि मैं पृष्ठ को नियंत्रक 2 पर ताज़ा करता हूँ तो चर अब $ rootScope पर उपलब्ध नहीं है। अगर मैं उपयोगकर्ता डेटा को साइन इन पर सहेज रहा हूं तो मैं यह सुनिश्चित कर सकता हूं कि पृष्ठ ताज़ा होने पर भी यह डेटा कहीं और कैसे सुलभ हो सकता है?
क्रेग माइल्स

19
@JakobStoeck इस उत्तर के साथ इसे मिलाएं और डेटा को रूटस्स्कोप पर रखने के साथ छोड़ दिया जाए। मुझे नहीं लगता कि यह सही भी है। डेटा के बिट्स के वैश्विक स्तर पर उपयोग और भंडारण के कोणीय तरीके क्या हैं?
user2483724

11
मैं उत्सुक हूं कि नुकसान एक सेवा का क्या है जो विशेष रूप से मूल्यों को संग्रहीत करने के लिए है। पृथक, केवल उस स्थान पर जहां आपको इसकी आवश्यकता हो, और आसानी से परीक्षण योग्य हो। नकारात्मक पक्ष क्या है?
ब्रायन

12
हे भगवान, हर कोई वास्तविक वैश्विक चर से क्यों डरता है, यदि आप जानते हैं कि आपका ऐप क्या होगा, तो सामान को ओवरकॉम्प्लिकेट करने के बजाय एक वास्तविक वैश्विक जेएस चर बनाएं
मैक्स यारी

93

यदि आप केवल एक मूल्य संग्रहीत करना चाहते हैं , तो प्रदाताओं पर कोणीय प्रलेखन के अनुसार , आपको मूल्य नुस्खा का उपयोग करना चाहिए:

var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');

फिर इसे इस तरह कंट्रोलर में इस्तेमाल करें:

myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
}]);

एक ही बात एक प्रदाता, कारखाने, या सेवा का उपयोग करके प्राप्त की जा सकती है क्योंकि वे "एक प्रदाता नुस्खा के शीर्ष पर सिंटैक्टिक चीनी" हैं, लेकिन मूल्य का उपयोग करने से आपको न्यूनतम सिंटैक्स के साथ जो चाहिए वह प्राप्त होगा।

अन्य विकल्प का उपयोग करना है $rootScope, लेकिन यह वास्तव में एक विकल्प नहीं है क्योंकि आपको इसे उन्हीं कारणों से उपयोग नहीं करना चाहिए, जिन्हें आपको अन्य भाषाओं में वैश्विक चर का उपयोग नहीं करना चाहिए। इसे संयम से इस्तेमाल करने की सलाह दी जाती है।

चूंकि सभी स्कोप आपको विरासत में मिलते हैं $rootScope, यदि आपके पास एक चर है$rootScope.data और कोई भूल जाता है dataजो पहले से ही परिभाषित है और $scope.dataएक स्थानीय दायरे में बनाता है तो आप समस्याओं में भाग लेंगे।


यदि आप इस मान को संशोधित करना चाहते हैं और यह आपके सभी नियंत्रकों के पास बना रहता है, तो किसी वस्तु का उपयोग करें और जावास्क्रिप्ट को ध्यान में रखते हुए गुणों को संशोधित करें। " एक संदर्भ की प्रतिलिपि" :

myApp.value('clientId', { value: 'a12345654321x' });
myApp.controller('DemoController', ['clientId', function DemoController(clientId) {
    this.clientId = clientId;
    this.change = function(value) {
        clientId.value = 'something else';
    }
}];

JSFiddle उदाहरण


1
जब मैंने एक दृश्य पर मूल्य बदल दिया, तो नया मान लगातार नहीं है। कैसे? क्या आप कृपया अपना उत्तर अपडेट कर सकते हैं और हमें बता सकते हैं कि आपका clientIdअपडेट कैसे किया जा सकता है?
ब्लेज़

@DeanOr क्या पृष्ठ के रिफ्रेश के बीच अद्यतन मूल्य को संरक्षित करना संभव है? यदि मैं पृष्ठ को रिफ्रेश करता हूं तो मान फिर से बढ़ जाता है।
नबरुन

आपको इसके लिए कुछ और उपयोग करना होगा, जैसे कि कुकी, स्थानीय भंडारण या डेटाबेस।
डीन या

1
मुझे यह सबसे अच्छा लगता है। मैं अब देव, मंच और ठेस के लिए निर्माण प्रक्रिया द्वारा संशोधित कर सकता हूं
jemiloii

1
ग्लोबल चर के समान स्थिरांक और मूल्यों के उपयोग की व्याख्या करने वाला एक सरल लेख है: ilikekillnerds.com/2014/11/…
RushabhG

36

का उपयोग कर AngularJS "वैश्विक चर" का उदाहरण $rootScope:

नियंत्रक 1 वैश्विक चर सेट करता है:

function MyCtrl1($scope, $rootScope) {
    $rootScope.name = 'anonymous'; 
}

नियंत्रक 2 वैश्विक चर को पढ़ता है:

function MyCtrl2($scope, $rootScope) {
    $scope.name2 = $rootScope.name; 
}

यहाँ एक काम कर रहा है jsFiddle: http://jsfiddle.net/natefriedman/3XT3F/1/


2
यह अलग-अलग गुंजाइश निर्देशों के विचारों में काम नहीं करता है। Jsfiddle.net/3XT3F/7 देखें । लेकिन आप इसके चारों ओर काम करने के लिए $ जड़ का उपयोग कर सकते हैं। Jsfiddle.net/3XT3F/10 देखें । के लिए धन्यवाद @natefaubion के लिए यह उनका कहना है
टोनी Lâmpada

2
ताज़ा होने पर, $ rootScope का मूल्य रिक्त होगा।
xyonme

$ rootScope.name को हार्डकोड करना कुछ मूल्य के बराबर है .. वास्तव में हमें इसे पढ़ने और इसे सेट करने की आवश्यकता है।

25

विकी पूल में एक और विचार जोड़ने के हित में, लेकिन एंगुलरजेएस valueऔर constantमॉड्यूल के बारे में क्या ? मैं केवल उन्हें स्वयं उपयोग करना शुरू कर रहा हूं, लेकिन यह मुझे लगता है कि ये शायद यहां सबसे अच्छा विकल्प हैं।

नोट: लेखन के समय के अनुसार, कोणीय 1.3.7 नवीनतम स्थिर है, मेरा मानना ​​है कि ये 1.2.0 में जोड़े गए थे, हालांकि चैंज के साथ इसकी पुष्टि नहीं की है।

आपको कितने परिभाषित करने की आवश्यकता है, इसके आधार पर, आप उनके लिए एक अलग फ़ाइल बनाना चाहते हैं। लेकिन मैं आमतौर पर अपने ऐप के ठीक पहले इन्हें परिभाषित करता हूं.config() आसान पहुंच के लिए ब्लॉक । क्योंकि ये अभी भी प्रभावी रूप से मॉड्यूल हैं, आपको इनका उपयोग करने के लिए निर्भरता इंजेक्शन पर भरोसा करना होगा, लेकिन उन्हें आपके ऐप मॉड्यूल के लिए "वैश्विक" माना जाता है।

उदाहरण के लिए:

angular.module('myApp', [])
  .value('debug', true)
  .constant('ENVIRONMENT', 'development')
  .config({...})

फिर किसी भी नियंत्रक के अंदर:

angular.module('myApp')
  .controller('MainCtrl', function(debug, ENVIRONMENT), {
    // here you can access `debug` and `ENVIRONMENT` as straight variables
  })

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


मुझे मूल्य मॉड्यूल बहुत उपयोगी और संक्षिप्त लगता है। विशेष रूप से तब जब आप इसे किसी कंट्रोलर के भीतर $ स्कोप वैरिएबल से बाँधते हैं, ताकि उस कंट्रोलर के लॉजिक या व्यू के भीतर बदलाव ग्लोबल वैरिएबल / वैल्यू / सर्विस के लिए बाध्य हो
बेन व्हीलर

20
// app.js or break it up into seperate files
// whatever structure is your flavor    
angular.module('myApp', [])    

.constant('CONFIG', {
    'APP_NAME' : 'My Awesome App',
    'APP_VERSION' : '0.0.0',
    'GOOGLE_ANALYTICS_ID' : '',
    'BASE_URL' : '',
    'SYSTEM_LANGUAGE' : ''
})

.controller('GlobalVarController', ['$scope', 'CONFIG', function($scope, CONFIG) {

    // If you wish to show the CONFIG vars in the console:
    console.log(CONFIG);

    // And your CONFIG vars in .constant will be passed to the HTML doc with this:
    $scope.config = CONFIG;
}]);

आपके HTML में:

<span ng-controller="GlobalVarController">{{config.APP_NAME}} | v{{config.APP_VERSION}}</span>

8
localStorage.username = 'blah'

यदि आप एक आधुनिक ब्राउज़र पर होने की गारंटी दे रहे हैं। हालांकि पता है कि आपके मूल्य सभी तार में बदल जाएंगे।

रीलोड के बीच कैश्ड होने का भी आसान लाभ है।


5
हे, मैं स्थानीय चर के माध्यम से सभी चर स्टोर करने जा रहा हूं। हम भी तो किसी तरह का हठ करेंगे! इसके अलावा, स्ट्रिंग सीमा के चारों ओर जाने के लिए, किसी फ़ंक्शन के .toString () को स्टोर करें, फिर जब जरूरत हो तब इसे निकाल लें!
शेज

@ शाज़ द्वारा पहले ही बताए गए अनुसार, यह दृढ़ता की समस्या है
ówubrówka

7

कृपया मुझे सही करें अगर मैं गलत हूं, लेकिन जब एंगुलर 2.0 रिलीज होती है तो मुझे विश्वास नहीं होता कि $rootScopeवह आसपास होगी। मेरा अनुमान इस तथ्य पर आधारित $scopeहै जिसे हटाया भी जा रहा है। जाहिर है कि नियंत्रक, अभी भी मौजूद रहेंगे, न कि केवल ng-controllerफैशन में। निर्देशों के बजाय नियंत्रकों को इंजेक्ट करने के लिए। यदि रिलीज आसन्न हो जाती है, तो सेवाओं को वैश्विक चर के रूप में उपयोग करना सबसे अच्छा होगा यदि आप एक आसान समय चाहते हैं तो 1.X से 2.0 तक स्विच करें।


मैं सहमत हूं, $ rootScope पर सीधे डेटा डालना Angular के संपूर्ण उद्देश्य के विरुद्ध है। थोड़ा समय लें और अपने कोड को ठीक से व्यवस्थित करें और यह आपकी मदद करेगा, न केवल AngularJS 2.x अपग्रेड में, बल्कि आमतौर पर आपके ऐप के विकास के दौरान यह अधिक जटिल हो जाता है।
कैटलिनबेर्टा

3
यदि $ rootScope हटा दिया जाता है, तो बस एक नई सेवा लिखें जिसे "$ rootScope" कहा जाता है :)
uylmz

3

आप पर्यावरण चर का उपयोग भी कर सकते हैं $windowताकि नियंत्रक के बाहर एक वैश्विक चर घोषित किया जा सके$watch

var initWatch = function($scope,$window){
    $scope.$watch(function(scope) { return $window.globalVar },
        function(newValue) {
            $scope.updateDisplayedVar(newValue);
    });
}

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


0

मुझे गलती से एक और तरीका मिला:

मैंने जो किया वह var db = nullउपरोक्त ऐप घोषणा को घोषित करने के लिए था और फिर इसे तब संशोधित किया app.jsजब मैंने इसे एक्सेस किया controller.js मैं इसे किसी भी समस्या के बिना एक्सेस करने में सक्षम था। इस पद्धति के साथ कुछ मुद्दे हो सकते हैं जिनके बारे में मुझे पता नहीं है, लेकिन यह है एक अच्छा समाधान मुझे लगता है।


0

यह कोशिश करो, आप $rootScopeनियंत्रक में इंजेक्ट करने के लिए मजबूर नहीं करेंगे ।

app.run(function($rootScope) {
    $rootScope.Currency = 'USD';
});

आप इसे केवल रन ब्लॉक में उपयोग कर सकते हैं क्योंकि कॉन्फ़िगरेशन ब्लॉक आपको $ rootScope की सेवा का उपयोग करने के लिए प्रदान नहीं करेगा।


0

यह वास्तव में बहुत आसान है। (यदि आप वैसे भी कोणीय 2+ का उपयोग कर रहे हैं।)

सीधे शब्दों में कहें

declare var myGlobalVarName;

कहीं आपके घटक फ़ाइल के शीर्ष पर (जैसे कि "आयात" बयानों के बाद), और आप अपने घटक के अंदर कहीं भी "myGlobalVarName" का उपयोग करने में सक्षम होंगे।


-2

आप भी कुछ ऐसा कर सकते हैं ।।

function MyCtrl1($scope) {
    $rootScope.$root.name = 'anonymous'; 
}

function MyCtrl2($scope) {
    var name = $rootScope.$root.name;
}

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