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"