Кутові 4/5/6 глобальних змінних


116

Я дійсно борюся зі створенням глобальних змінних у своїй програмі Angular 2.

Я вже гуглив і читав багато публікацій на StackOverflow на цьому протягом останніх 3 годин, проте, схоже, я просто не можу змусити його працювати. Я дуже сподіваюся, що ти можеш мені допомогти, і я вибачаюся за те, що задаю це питання.

Тож у мене є мій файл під назвою globals.ts , який виглядає приблизно так:

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


@Injectable()
export class Globals {

  var role = 'test';

}

І я хочу використовувати змінну роль у моєму перегляді HTML свого компонента, як це:

{{ role }} 

Я вже додав файл globals.ts до свого app.module.ts таким чином:

providers: [
  Globals
],

Що б я не робив у цьому файлі, він просто не працював. Те, що я не хочу робити, - це імпортувати файл globals.ts у кожен компонент вручну, саме тому я хочу використовувати функцію провайдерів.

Я дуже сподіваюся, що ти зможеш мені знову допомогти і шкодувати.

З найкращими побажаннями,

AE


4
export class Globals { var role = 'test'; }<- що це?
zerkms

Це повинен бути мій клас Globals, в якому я хочу зберігати свої глобальні змінні. Наприклад, змінна "роль", яка зараз повинна мати в ній рядок "тест", просто перевірити, чи працюють глобальні змінні.
AE

Однак це невірний машинопис.
zerkms

Чи слід видалити "var"?
AE

як щодо використання localStorage?
suhailvs

Відповіді:


180

Ви можете отримати доступ до Globalsоб'єкта з будь-якої точки програми через інжекцію кутової залежності . Якщо ви хочете вивести Globals.roleзначення в шаблоні якогось компонента, вам слід ввести його Globalsчерез конструктор компонента, як і будь-яка служба:

// hello.component.ts
import { Component } from '@angular/core';
import { Globals } from './globals';

@Component({
  selector: 'hello',
  template: 'The global role is {{globals.role}}',
  providers: [ Globals ] // this depends on situation, see below
})

export class HelloComponent {
  constructor(public globals: Globals) {}
}

Я надав Globalsу HelloComponent, але замість цього він міг бути наданий у якомусь HelloComponent'sбатьківському компоненті чи навіть у AppModule. Це не матиме значення, поки у вас Globalsє лише статичні дані, які неможливо змінити (скажімо, лише константи). Але якщо це неправда, і, наприклад, різні компоненти / сервіси можуть захотіти змінити ці дані, тоді це Globalsповинно бути однотонним . У такому випадку його слід забезпечити на найвищому рівні ієрархії, де він буде використовуватися. Скажімо, це AppModule:

import { Globals } from './globals'

@NgModule({
  // ... imports, declarations etc
  providers: [
    // ... other global providers
    Globals // so do not provide it into another components/services if you want it to be a singleton
  ]
})

Крім того, неможливо використовувати var так, як ви зробили, так і має бути

// globals.ts
import { Injectable } from '@angular/core';

@Injectable()
export class Globals {
  role: string = 'test';
}

Оновлення

Нарешті, я створив просту демонстрацію на stackblitz , де Globalsрозділяється сингл між 3 компонентами, і один з них може змінити значення Globals.role.


3
Але коли я отримую його в іншому компоненті (щось = globals.role;), я отримую 'test' .. Не значення, яке я призначив йому.
пунктур

3
@punkouter Я оновив відповідь за допомогою демонстраційного посилання Plunker. Сподіваюся, це допоможе вам!
dhilt

3
Це дещо стара тема, але я просто хочу сказати, що люблю тебе. Врятував мій день!
Nie Selam

2
@AtulStha Я просто перемістив демонстрацію з Plunker на Stackblitz, дякую за проблему.
dhilt

1
@GauravSachdeva Ви можете опублікувати своє питання як окреме запитання на ТАК, я вважаю, що це був би найкращий варіант. Додайте посилання на нього в коментарях, якщо ви хочете, щоб я бачив його.
dhilt

22

Я використовую для цього середовище. Він працює автоматично, і вам не доведеться створювати нові послуги для ін'єкцій, і найкорисніше для мене, не потрібно імпортувати через конструктор.

1) Створіть змінну середовища у середовищі

export const environment = {
    ...
    // runtime variables
    isContentLoading: false,
    isDeployNeeded: false
}

2) Імпортуйте Environment.ts у файл * .ts та створіть загальну змінну (тобто "env"), щоб мати можливість використовувати в HTML-шаблоні

import { environment } from 'environments/environment';

@Component(...)
export class TestComponent {
    ...
    env = environment;
}

3) Використовуйте його в шаблоні ...

<app-spinner *ngIf='env.isContentLoading'></app-spinner>

в * .ts ...

env.isContentLoading = false 

(або просто environment.isContentLoading у випадку, якщо він вам не потрібен для шаблону)


Ви можете створити свій власний набір глобалів у середовищі.

export const globals = {
    isContentLoading: false,
    isDeployNeeded: false
}

і безпосередньо імпортувати ці змінні (y)


1
Що робити, коли ви змушуєте нарощувати виробництво? У вас все є в двох місцях?
Мальпері

2
Це найкращий спосіб. @Mulperi Не потрібно створювати глобальні ресурси в environment.ts. Просто створіть globals.ts в каталозі додатків із вище експортом та імпортуйте цей файл там, де ви хочете використовувати ці глобалі.
PrasadW

1
Я згоден. Нещодавно я змінив це рішення саме так, як вказував @PrasadW.
Мартін Славковський

Нові кутові версії зараз використовують саме такий підхід за замовчуванням. Є environments/environment.tsі environments/environment.prod.tsякі замінюються автоматично.
килимок

0

Насправді не рекомендується, але жоден з інших відповідей не є дійсно глобальними змінними. Для справді глобальної змінної ви могли б це зробити.

Index.html

<body>
  <app-root></app-root>
  <script>
    myTest = 1;
  </script>
</body>

Компонент або щось інше в кутовій

..поруч праворуч після імпорту:

declare const myTest: any;

... пізніше:

console.warn(myTest); // outputs '1'

-2

Ви можете використовувати об’єкт Window та отримати доступ до нього будь-де. example window.defaultTitle = "мій заголовок"; тоді ви можете отримати доступ до window.defaultTitle, не імпортуючи нічого.


Це те, чого хочеться уникнути.
Скандинав
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.