मैं कोणीय 2 / टाइपस्क्रिप्ट में वैश्विक चर कैसे घोषित कर सकता हूं? [बन्द है]


164

मैं चाहूंगा कि कुछ चर भाषा Angular 2में हर जगह सुलभ हों Typescript। मुझे इसे पूरा करने के बारे में कैसे जाना चाहिए?


2
यदि वे स्थिर चर हैं तो सेवाओं का उपयोग करने की कोई आवश्यकता नहीं है। बस किसी फ़ाइल में एक चर जोड़ें और फिर इसे हर जगह आयात करें, जहां आपको इसकी आवश्यकता है।
एरिक मार्टिनेज

दुर्भाग्य से Angular2 रनटाइम में अपवाद है, कह रही है Uncaught ReferenceError: Settings is not definedSettingsसार्वजनिक स्थैतिक चर वाले वर्ग को निर्यात करने के लिए सेट किया गया है और इसका उपयोग करने के लिए आयात किया गया है।
सेन जैकब

मुझे पता है कि यह पोस्ट पुरानी है और कई मान्य उत्तर हैं। लेकिन जैसे एरिक ने उल्लेख किया है। यदि इसका एक साधारण मूल्य जिसे आप घोषित करना चाहते हैं और अपने आवेदन के माध्यम से उपयोग करना चाहते हैं तो आप एक वर्ग बना सकते हैं और एक स्थिर संपत्ति के साथ वर्ग का निर्यात कर सकते हैं। स्टेटिक चर वर्ग के उदाहरण के बजाय एक वर्ग से जुड़े होते हैं। आप वर्ग का आयात कर सकते हैं और वर्ग से संपत्ति तक पहुँचने में सक्षम होंगे।
डी वेट एलिस

जवाबों:


195

यहाँ सबसे सरल समाधान w / o है Serviceऔर न ही Observer:

वैश्विक चर एक फ़ाइल में उन्हें निर्यात करें।

//
// ===== File globals.ts    
//
'use strict';

export const sep='/';
export const version: string="22.2.2";    

किसी अन्य फ़ाइल में ग्लोबल्स का उपयोग करने के लिए एक importस्टेटमेंट का उपयोग करें : import * as myGlobals from 'globals';

उदाहरण:

// 
// ===== File heroes.component.ts    
//
import {Component, OnInit} from 'angular2/core';
import {Router} from 'angular2/router';
import {HeroService} from './hero.service';
import {HeroDetailComponent} from './hero-detail.component';
import {Hero} from './hero';
import * as myGlobals from 'globals'; //<==== this one (**Updated**)

export class HeroesComponent implements OnInit {
    public heroes: Hero[];
    public selectedHero: Hero;
    // 
    //
    // Here we access the global var reference.
    //  
    public helloString: string="hello " + myGlobals.sep + " there";

         ...

        }
    }

धन्यवाद @ एरिक-मार्टिनेज


3
आयात कथन पर एक त्रुटि मिली। का उपयोग करना पड़ाimport * as globs from 'globals'
माइक एम।

13
आपने आयात के बजाय "आवश्यकता" का उपयोग क्यों किया?
अय्याश

4
मैं export constइसके बजाय का उपयोग करेगा export var- आप वास्तव में यह सुनिश्चित करना चाहते हैं कि उन वैश्विक चर को बदला नहीं जा सकता है
मिशाल बोस्का

1
इस प्रकार आयात करना अब टाइपस्क्रिप्ट में मान्य नहीं है। कृपया अपना उत्तर अपडेट करें। सही होगा:import * as myGlobals from 'globals'
मिक

7
import * as myGlobals from './path/to/globals';
तीमुथियुस ज़ोन

89

मुझे @supercobra से भी समाधान पसंद है। मैं बस इसे थोड़ा सुधारना चाहूंगा। यदि आप किसी ऑब्जेक्ट को निर्यात करते हैं जिसमें सभी स्थिरांक होते हैं, तो आप आवश्यकता का उपयोग किए बिना केवल es6 मॉड्यूल का आयात कर सकते हैं ।

मैं भी गुण का इस्तेमाल किया। सही गुणों स्थिर बनने के लिए। यदि आप विषय में रुचि रखते हैं, तो आप इस पोस्ट को पढ़ सकते हैं ।

// global.ts

 export const GlobalVariable = Object.freeze({
     BASE_API_URL: 'http://example.com/',
     //... more of your variables
 });

आयात का उपयोग करके मॉड्यूल देखें।

//anotherfile.ts that refers to global constants
import { GlobalVariable } from './path/global';

export class HeroService {
    private baseApiUrl = GlobalVariable.BASE_API_URL;

    //... more code
}

यह मेरे लिए सबसे अच्छा समाधान है क्योंकि (1) यह कम से कम मात्रा में कोड के साथ सबसे सरल है और (2) इसके लिए आपको हर एक घटक या उस स्थान पर कुछ darn सेवा को इंजेक्ट करने की आवश्यकता नहीं है जहाँ आप इसका उपयोग करना चाहते हैं, और न ही यह। आपको @NgModule में इसे पंजीकृत करने की आवश्यकता है। मैं अपने जीवन के लिए यह पता नहीं लगा सकता कि ऐसा करने के लिए कोणीय 2 सेवा बनाना क्यों ज़रूरी होगा, लेकिन शायद कुछ ऐसा है जो मैं देख रहा हूँ? मैं अभी के लिए इस महान समाधान का उपयोग कर रहा हूं, लेकिन कृपया मुझे बताएं कि अन्य अधिक जटिल उत्तर यहां क्यों बेहतर हैं?
फायरड्रैगन

8
आपका GlobalVariable एक परिवर्तनशील नहीं है। इसकी एक स्थिरांक है।
प्रिया आर

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

Object.freeze का डाउन साइड यह है कि मान टाइप नहीं किए गए हैं। वैसे भी, कक्षा में मूल्यों को लपेटना मेरे दृष्टिकोण से एक बेहतर डिजाइन है। इसलिए हमें टाइप की गई संपत्तियों और सच्चे स्थिरांक के बीच चयन करना होगा।
हार्प्स

GlobalVariable.BASE_API_URL को किसी अन्य घटक में कैसे सेट करें ..?
सुनील चौधरी

59

एक साझा सेवा सबसे अच्छा तरीका है

export class SharedService {
  globalVar:string;
}

लेकिन आपको इसे पंजीकृत करते समय बहुत सावधानी बरतने की जरूरत है ताकि आप अपने पूरे आवेदन के लिए एक भी उदाहरण साझा कर सकें। आपको अपना आवेदन पंजीकृत करते समय इसे परिभाषित करने की आवश्यकता है:

bootstrap(AppComponent, [SharedService]);

लेकिन providersअपने घटकों की विशेषताओं के भीतर इसे फिर से परिभाषित करने के लिए नहीं :

@Component({
  (...)
  providers: [ SharedService ], // No
  (...)
})

अन्यथा घटक और इसके उप घटकों के लिए आपकी सेवा का एक नया उदाहरण बनाया जाएगा।

आप इस सवाल पर एक नज़र डाल सकते हैं कि एंगुलर 2 में निर्भरता इंजेक्शन और श्रेणीबद्ध इंजेक्शन कैसे काम करते हैं:

आप नोटिस कर सकते हैं कि Observableजब आप अपने वैश्विक गुणों को बदलते हैं, तो आप अपने आवेदन के कुछ हिस्सों को सूचित करने के लिए सेवा में गुणों को भी परिभाषित कर सकते हैं:

export class SharedService {
  globalVar:string;
  globalVarUpdate:Observable<string>;
  globalVarObserver:Observer;

  constructor() {
    this.globalVarUpdate = Observable.create((observer:Observer) => {
      this.globalVarObserver = observer;
    });
  }

  updateGlobalVar(newValue:string) {
    this.globalVar = newValue;
    this.globalVarObserver.next(this.globalVar);
  }
}

अधिक विवरण के लिए यह प्रश्न देखें:


लगता है कि यह एक अलग है। लगता है @ Rat2000 को लगता है कि हमारा जवाब गलत है। मैं आमतौर पर इस निर्णय को दूसरों से प्रतिस्पर्धात्मक जवाब देने के लिए छोड़ देता हूं, लेकिन अगर उन्हें यकीन है कि हमारे उत्तर गलत हैं तो मुझे लगता है कि यह मान्य है। डॉक्स वह मेरे जवाब के लिए एक टिप्पणी में जुड़ा हुआ है उल्लेख है कि यह अस्वीकृत है, लेकिन मुझे कोई नुकसान नहीं है और डॉक्स में तर्क काफी कमजोर हैं। प्रदाताओं को बूटस्ट्रैप में जोड़ना भी काफी आम है। वैसे भी इस तर्क का उद्देश्य क्या होगा। और इसके बारे में क्या HTTP_PROVIDERSसमान है, उन्हें भी नहीं जोड़ा जाना चाहिए bootstrap()?
गुंटर ज़ोचबॉयर

2
हां, मैं सिर्फ डॉको में तर्क और अनुभाग पढ़ता हूं। ईमानदारी से, मैं वास्तव में यह नहीं समझता कि यह डॉक्टर से हतोत्साहित क्यों है। क्या यह एक तार्किक विभाजन को परिभाषित करने का एक तरीका है: बूटस्ट्रैपिंग के दौरान Angular2 कोर विशिष्ट (रूटिंग प्रदाता, http प्रदाता) क्या है और एप्लिकेशन घटक इंजेक्टर में एप्लिकेशन-विशिष्ट क्या है। कहा कि रूट रूट वन (बूटस्ट्रैपिंग के दौरान परिभाषित) के लिए हमारे पास केवल एक सब इंजेक्टर (एप्लिकेशन एक) हो सकता है। क्या मुझे कुछ याद है? इसके अलावा डॉक में पदानुक्रमित इंजेक्टरों के संबंध में, सेवा प्रदाताओं को रूट इंजेक्टर के भीतर परिभाषित किया जाता है; ;-)
थियरी टेम्पलर

3
मेरा एकमात्र तर्क यह है कि गुंजाइश को यथासंभव संकीर्ण रखना और रूट घटक का उपयोग करना कम से कम सिद्धांत में उपयोग करने की तुलना में थोड़ा संकीर्ण है, bootstrap()लेकिन व्यवहार में यह कोई फर्क नहीं पड़ता। मुझे लगता boostrap()है कि कोड को समझना आसान बनाने में उन्हें सूचीबद्ध करना । एक घटक में प्रदाता, निर्देश, एक टेम्पलेट होता है। मुझे लगता है कि यह वैश्विक प्रदाताओं के बिना भी अतिभारित है। इसलिए मुझे पसंद है bootstrap()
गुंटर ज़ोचबॉयर

2
और एक ऐसे वैश्विक चर का संदर्भ कैसे देता है? सेवा को बूटस्ट्रैप करने के बाद भी, alert(globalVar)त्रुटि का परिणाम होता है।
18:29 पर phil294

मैंने अभी तक इसकी कोशिश नहीं की है, लेकिन आप कुछ इस तरह चाहते हैं: अलर्ट (this.SaringService.globalVar)
पेड़_आरे_गेट

39

उदाहरण के लिए देखें कोणीय 2 - साझा सेवाओं का कार्यान्वयन

@Injectable() 
export class MyGlobals {
  readonly myConfigValue:string = 'abc';
}

@NgModule({
  providers: [MyGlobals],
  ...
})

class MyComponent {
  constructor(private myGlobals:MyGlobals) {
    console.log(myGlobals.myConfigValue);
  }
}

या व्यक्तिगत मूल्य प्रदान करते हैं

@NgModule({
  providers: [{provide: 'myConfigValue', useValue: 'abc'}],
  ...
})

class MyComponent {
  constructor(@Inject('myConfigValue') private myConfigValue:string) {
    console.log(myConfigValue);
  }
}

Angular2 बीटा 7 (मुझे लगता है) के बाद से आपको अपनी सेवा को सीधे मूल घटक (उर्फ बूटस्ट्रैप) में पंजीकृत नहीं करना चाहिए। यदि आप अपने एप्लिकेशन में कुछ ओवरराइड करना चाहते हैं तो आप एक विशिष्ट प्रदाता को इंजेक्ट कर सकते हैं।
Mihai

1
पक्का नहीं आपका क्या मतलब है। बेशक आप में एक सेवा पंजीकृत कर सकते हैं bootstrap()bootstrap()और जड़ घटक दो अलग-अलग चीजें हैं। जब आप कॉल bootstrap(AppComponent, [MyService])करते हैं तो आप सेवा को पंजीकृत करते हैं boostrap()और AppComponentरूट घटक है। डॉक्स ने कहीं उल्लेख किया है कि यह रूट घटकों में प्रदाताओं (सेवा) को पंजीकृत करने के लिए पसंद किया जाता है, providers: ['MyService']लेकिन मुझे bootstrap()अभी तक इसके पक्ष में या इसके विपरीत किसी भी तर्क का पता नहीं चला है।
गुंटर ज़ोचबॉयर

आप कोणीय 2guide अनुभाग निर्भरता इंजेक्शन ( angular.io/docs/ts/latest/guide/d dependency-injection.html ) में अपना तर्क पा सकते हैं । जैसे वे कहते हैं, आप इसे कर सकते हैं, लेकिन यह अस्वीकृत है। यह उपयोगकर्ता कुछ चुड़ैल स्पष्ट करने के लिए सबसे अच्छा तरीका पूछ रहा है स्पष्ट रूप से आपका समाधान corect नहीं है। वही @ThierryTemplier
Mihai

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

1
वर्ग निर्यात करने के लिए मत भूलना
Demodave करें

15

एप्लिकेशन / globals.ts में ग्लोबल्स क्लास बनाएं :

import { Injectable } from '@angular/core';

Injectable()
export class Globals{
    VAR1 = 'value1';
    VAR2 = 'value2';
}

आपके घटक में:

import { Globals } from './globals';

@Component({
    selector: 'my-app',
    providers: [ Globals ],
    template: `<h1>My Component {{globals.VAR1}}<h1/>`
})
export class AppComponent {
    constructor(private globals: Globals){
    }
}

नोट : आप ग्लोबल्स सेवा प्रदाता को घटक के बजाय सीधे मॉड्यूल में जोड़ सकते हैं, और आपको उस मॉड्यूल में प्रत्येक घटक के लिए प्रदाता के रूप में जोड़ने की आवश्यकता नहीं होगी।

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [ Globals ],
    bootstrap: [ AppComponent ]
})
export class AppModule {
}

यह सबसे अच्छा जवाब है, क्योंकि यह ऐप में प्रत्येक घटक में सेवा को जोड़ने की तुलना में अधिक पोर्टेबल दृष्टिकोण प्रदान करता है। धन्यवाद!
विडाल क्वेवेदो

5
कोड काम कर रहा है। लेकिन ध्यान दें कि वर्ग Globalsको इंजेक्शन के साथ जोड़ने का providers: [ ... ]मतलब है कि आप एक घटक के अंदर एक मूल्य नहीं बदल सकते हैं और फिर एक दूसरे घटक के अंदर अद्यतन मूल्य पूछ सकते हैं। हर बार जब आप Globalsइसे इंजेक्ट करते हैं तो यह एक ताजा उदाहरण है। यदि आप इस व्यवहार को बदलना चाहते हैं, तो बस प्रदाता के रूप में जोड़ें Globals
तिमो बेहर

बस एक नोट, यह होना चाहिए@Injectable()
mast3rd3mon

11

Angular2 (v2.2.3) के लिए IMHO उन सेवाओं को जोड़ने का सबसे अच्छा तरीका है जिनमें वैश्विक चर शामिल हैं और उन्हें एनोटेशन के providersअंदर टैग के बिना घटकों में इंजेक्ट किया जाता है @Component। इस तरह से आप घटकों के बीच जानकारी साझा करने में सक्षम हैं।

एक नमूना सेवा जो एक वैश्विक चर का मालिक है:

import { Injectable } from '@angular/core'

@Injectable()
export class SomeSharedService {
  public globalVar = '';
}

एक नमूना घटक जो आपके वैश्विक चर के मूल्य को अद्यतन करता है:

import { SomeSharedService } from '../services/index';

@Component({
  templateUrl: '...'
})
export class UpdatingComponent {

  constructor(private someSharedService: SomeSharedService) { }

  updateValue() {
    this.someSharedService.globalVar = 'updated value';
  }
}

एक नमूना घटक जो आपके वैश्विक चर का मूल्य पढ़ता है:

import { SomeSharedService } from '../services/index';

@Component({
  templateUrl: '...'
})
export class ReadingComponent {

  constructor(private someSharedService: SomeSharedService) { }

  readValue() {
    let valueReadOut = this.someSharedService.globalVar;
    // do something with the value read out
  }
}

ध्यान दें कि आपके एनोटेशन में नहीं जोड़ा providers: [ SomeSharedService ]जाना चाहिए । इस लाइन इंजेक्शन को नहीं जोड़ने से आपको हमेशा एक ही उदाहरण मिलेगा । यदि आप लाइन जोड़ते हैं तो एक ताज़ा बनाया गया उदाहरण इंजेक्ट किया जाता है।@ComponentSomeSharedService


लेकिन प्रदाताओं की लाइन को जोड़ने के बिना, मुझे इस तरह एक त्रुटि मिली:Unhandled Promise rejection: No provider for SomeSharedService
रॉकी

समझा। मुझे providers: [SomeSharedService]मूल मॉड्यूल फ़ाइल में जोड़ना चाहिए । धन्यवाद।
रॉकी

यह काम नहीं करता जब हम आलसी लोडिंग मॉड्यूल हैं।
lpradhap

9

मैं सबसे अच्छा तरीका नहीं जानता, लेकिन सबसे आसान तरीका अगर आप एक घटक के अंदर एक वैश्विक चर को परिभाषित करना चाहते हैं तो चर का उपयोग windowइस तरह से लिखना है:

window.GlobalVariable = "what ever!"

आपको इसे बूटस्ट्रैप या अन्य स्थानों पर आयात करने के लिए पास करने की आवश्यकता नहीं है, और यह विश्व स्तर पर सभी जेएस (न केवल कोणीय 2 घटकों) के लिए सुलभ है।


1
मैं कहूंगा कि यह सबसे खराब तरीका है। स्टैटिक वेरिएबल का उपयोग करना अधिक जटिल नहीं है, लेकिन यह बदसूरत भी नहीं है ;-)
गुंटर ज़ोचबॉयर

2
मैं मानता हूं कि इसे प्रबंधित करना मुश्किल है। हालाँकि, मैंने उन्हें विकास में उपयोग करने के लिए समाप्त कर दिया, जब तक कि मुझे वह नहीं मिला जो मैं प्रस्तुतियों में रखना चाहता हूं। स्टैटिक वैरिएबल में आपको उन्हें बार-बार इम्पोर्ट करना होता है, हर जगह जो आप इस्तेमाल करना चाहते हैं, उसके बगल में एक ऐसा केस था जिसे मैं कोणीय कंपोनेंट्स में jquery के साथ चलते-फिरते देख रहा था - कोई टेम्प्लेट नहीं था, और स्टैटिक का इस्तेमाल करके डोम के उत्पादन के लिए इवेंट जोड़ना चर दर्द है।
महदी जदलिहा

1
इसके अलावा, यह स्थिर नहीं है, आप हर जगह से मूल्य बदल सकते हैं!
महदी जदलिहा

1
यह सर्वर साइड रेंडरिंग को भी मिटा देता है। खिड़की या दस्तावेज़ में सीधे हेरफेर करने से दूर रहें।
एरिक होन

1
माना। लेकिन मैं व्यक्तिगत रूप से अपने जीवन में किसी भी दिशानिर्देश का पालन नहीं करता (यदि मैं इससे बेहतर कर सकता था)।
महदी जदलिहा

7

यही तरीका है कि मैं इसका उपयोग करता हूं:

global.ts

export var server: string = 'http://localhost:4200/';
export var var2: number = 2;
export var var3: string = 'var3';

इसका उपयोग करने के लिए बस उसी तरह आयात करें:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import * as glob from '../shared/global'; //<== HERE

@Injectable()
export class AuthService {
    private AuhtorizationServer = glob.server
}

अनुशंसित: अनुशंसित रूप में उपसर्गित "_" गिराया गया।


निजी गुणों के लिए उपसर्ग के रूप में "_" का उपयोग न करें। github.com/Microsoft/TypeScript/wiki/Coding-guidelines
crh225

4

मुझे लगता है कि सबसे अच्छा तरीका यह है कि आप जहां चाहें वहां निर्यात और आयात करके अपने आवेदन में वैश्विक चर के साथ एक वस्तु साझा कर सकते हैं।

पहले globals.ts उदाहरण के लिए एक नई .ts फ़ाइल बनाएँ और एक ऑब्जेक्ट घोषित करें। मैंने इसे ऑब्जेक्ट प्रकार दिया लेकिन आप किसी भी प्रकार या {} का उपयोग कर सकते हैं

export let globalVariables: Object = {
 version: '1.3.3.7',
 author: '0x1ad2',
 everything: 42
};

इसके बाद इसे आयात करें

import {globalVariables} from "path/to/your/globals.ts"

और इसका उपयोग करें

console.log(globalVariables);

3

मुझे @supercobra का उत्तर पसंद है, लेकिन मैं कास्ट कीवर्ड का उपयोग करूंगा क्योंकि यह ES6 में उपलब्ध है:

//
// ===== File globals.ts    
//
'use strict';

export const sep='/';
export const version: string="22.2.2"; 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.