Угловые 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

AE
источник
4
export class Globals { var role = 'test'; }<- что это?
zerkms
Это должен быть мой класс Globals, в котором я хочу хранить свои глобальные переменные. Например, переменная «роль», в которой прямо сейчас должна быть строка «test», просто чтобы проверить, работают ли глобальные переменные.
AE
Однако это недопустимый машинописный текст.
zerkms
Стоит ли убрать "вар"?
AE
как насчет использования localStorage?
suhailvs

Ответы:

180

Вы можете получить доступ к Globalsобъекту из любой точки вашего приложения с помощью внедрения зависимостей Angular . Если вы хотите вывести 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 , где single Globalsиспользуется тремя компонентами, и один из них может изменять значение Globals.role.

dhilt
источник
3
Но когда я получаю его в другом компоненте (something = globals.role;), я получаю "test" .. Не то значение, которое я ему присвоил.
punkouter
3
@punkouter Я обновил ответ демонстрационной ссылкой Plunker. Надеюсь, это поможет вам!
dhilt
3
Это несколько старая тема, но я просто хочу сказать, что люблю тебя. Спас мой день!
Nie Selam
2
@AtulStha Я только что переместил демо с Plunker на Stackblitz, спасибо за проблему.
dhilt 04
1
@GauravSachdeva. Вы можете опубликовать свой вопрос как отдельный вопрос на SO, я считаю, что это будет лучший вариант. Добавьте ссылку на нее в комментариях, если хотите, чтобы я ее увидел.
dhilt 05
22

Я использую для этого среду. Он работает автоматически, и вам не нужно создавать новую услугу для инъекций, и, что наиболее полезно для меня, не нужно импортировать через конструктор.

1) Создайте переменную окружения в вашем environment.ts

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, если он вам не нужен для шаблона)


Вы можете создать свой собственный набор глобальных объектов в environment.ts следующим образом:

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

и напрямую импортировать эти переменные (y)

Мартин Славковский
источник
1
А что насчет того, когда вы создаете производственную сборку? У вас все есть в двух местах?
Mulperi
2
Это лучший способ. @Mulperi Не обязательно создавать глобальные объекты в environment.ts. Просто создайте globals.ts в каталоге приложения с указанным выше экспортом и импортируйте этот файл, где вы хотите использовать эти глобальные файлы.
PrasadW
1
Я согласен. Недавно я изменил это решение точно так, как указал @PrasadW.
Мартин Славковский
Новые версии Angular по умолчанию используют именно этот подход. Есть environments/environment.tsи environments/environment.prod.tsкоторые заменяются автоматически.
коврик
0

Не рекомендуется, но другие ответы не являются глобальными переменными. Для действительно глобальной переменной вы можете это сделать.

Index.html

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

Компонент или что-то еще в Angular

..вверху справа после импорта:

declare const myTest: any;

...потом:

console.warn(myTest); // outputs '1'
Helzgate
источник
-2

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

Джастис Аддико
источник
Это то, чего он хочет избежать.
Scandinave