Angular2 поставщик глобальных услуг

/app
        - app.component.ts 
        - app.component.html (hide/show: menu bar)
        - app.global.service.ts (Public varible LoginSuccess:boolean)
        - main.ts
        /student
            - student.ts
            - student.service.ts
            - student.component.ts
            - student.component.html
        /security
            - login.component.ts (LoginSuccess = true)
            - login.component.html

В моем приложении Angular2 у меня есть простая необходимость, когда я хочу показать скрытую панель меню, основанную на успехе входа в систему. Для этого я создал службу, у которой есть только логический логин LoginSuccess, который я бы установил на компоненте входа и использовал бы на app.component.html для тега [hidden]=LoginSuccess nav.

Проблема, с которой я столкнулась, даже после ввода значения app.global.service.ts thru constructor of app.component.ts & login.component.ts не сохраняется и каждый конструктор создает новый объект app.global.service.ts.

Вопрос: Как я могу добиться сохранения единственной ценности в приложении через службу. Где-то в Angular2 docs я прочитал, что Injectable service является singleton.

Ответ 1

Вы должны предоставить GlobalService при загрузке, а не для каждого компонента:

bootstrap(AppComponent, [GlobalService])

@Component({
  providers: [], // yes
  // providers: [GlobalService], // NO.
})
class AppComponent {
  constructor(private gs: GlobalService) {
    // gs is instance of GlobalService created at bootstrap
  }
}

Таким образом, GlobalService будет одиночным.

Для более продвинутого подхода см. этот ответ.

Ответ 2

У вас должен быть app.component.ts, и вместо того, чтобы разворачивать внутри app.module.ts, вы вводите службу в app.component.ts.

...
import { MusicService } from './Services/music-service';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html',
    providers: [MusicService],
    ...
})
export class AppComponent {

constructor(private MS: MusicService) {

}
...

Это основано на текущей строке Angular2. Поэтому внутри index.html вы должны иметь <app-root>, где загружается AppComponent.

Теперь, чтобы использовать его внутри любого другого компонента, просто импортируйте его:

import { MusicService } from './Services/music-service';

и инициализируйте его:

constructor(private MS: MusicService) {

}

Резюме:

  • Импортировать в app.component.ts
  • Вставить в app.component.ts как provider
  • Инициализировать в конструкторе
  • Повторите шаг 2,3 для использования любого другого компонента, чтобы использовать его в

Ссылка: Angular Инъекция зависимостей

Ответ 3

Как Saxsa, ключевым моментом является определение поставщика услуг внутри инжектора приложения, а не на каждом уровне компонента. Будьте осторожны, чтобы не определять поставщика услуг дважды... В противном случае у вас все еще будут отдельные экземпляры службы.

Таким образом вы сможете использовать один и тот же экземпляр службы.

Это происходит из-за иерархических инжекторов Angular2. Для более подробной информации вы можете посмотреть на этот вопрос:

Ответ 4

Начиная с окончательной версии (Angular 2.0.0):

Импортируйте службу и введите ее в массив поставщиков следующим образом:

import { GlobalService } from './app.global.service';

//further down:
@NgModule({
  bootstrap: [ App ],
  declarations: [
    // Your components should go here 
  ],
  imports: [ 
    // Your module imports should go here
  ],
  providers: [ 
    ENV_PROVIDERS // By Angular
    // Your providers should go here, i.e.
    GlobalService
  ]
});

Ответ 5

Я просто добавлю, потому что я застрял в этой точке, хотя я использовал Singelton, вам также нужно использовать стратегию маршрутизации Angular:

Вы не можете использовать href= "../my-route"

заставляет это запускать все новое приложение:

вместо этого вы должны использовать: routerLink = "../my-route"