Angular 2: Создание "сервиса глобальных параметров" и подписка на его параметры
Я работаю над приложением Angular 2, где я хочу хранить некоторые "глобальные переменные" (состояние) для разных компонентов. Это может быть выбор пользователя year
а также customerId
и т. д. Все компоненты должны иметь к ним доступ для использования в GET
вызовы API/ Backend.
Я реализовал параметры маршрутизатора, так что можно передавать параметры в компонент таким образом, но мне легче работать с ним, чем поддерживать состояние, передавая параметры через маршрутизатор при каждом щелчке. Надеюсь, это имеет смысл.
Во всяком случае, после этого вопроса на Stackru, я настроил следующее service
:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/share';
import { Observer } from 'rxjs/Observer';
interface params {
year: string;
customerId: number;
};
@Injectable()
export class ParameterService {
// initial (test) values:
p: params = {
year: "2017",
customerId: 101
};
constructor() {}
}
Кажется, это работает двумя способами, позволяя моим компонентам получать и устанавливать параметры следующим образом:
// get global value
this.year = this._parameterService.p['year'];
// set global value
this._parameterService.p['year'] = "2018";
И привязка данных тоже работает. Это связано с p
быть классом (объектом), а не просто обращаться к string
year
напрямую, насколько я понимаю. Если я изменю year
значение от component1
, затем component2
(ниже) будет отражать изменение:
<h1>Year = {{this._parameterService.p['year']}}</h1>
Все, что мне нужно сделать, это ввести ParameterService
в любой компонент, который нуждается в этом, и я готов. Тем не менее, я не могу понять, как расширить это так, чтобы компонент перезагрузился (выполнить другой GET
вызов) с измененным параметром.
Для параметров маршрутизатора компонент "подписывается" наparams
в егоngOnInit
метод, заставляющий его "обновляться" при изменении маршрута:
ngOnInit(): void {
this.sub = this._route.params.subscribe(params => {
this.customerId = params['customerId'];
this.year = params['year'];
this.resetComponentState(); // based on new parameter this time
});
}
resetComponentState(): void {
this._otherService.getDataFromApi(this.year)
.then(
myData => this.myData = myData,
error => this.errorMessage = <any>error);
}
Как я могу добиться того же, основываясь на ParameterService
? Можно ли как-то "связать" this.year
с this._parameterService.p['year']
вresetComponentState()
? Кстати, я пытался сделать это, но безрезультатно.
ОБНОВЛЕНИЕ- это полный компонент, который я хочу обновить при изменении параметров (а не только при изменении параметров маршрутизатора):
import { Component, Input, OnInit } from '@angular/core';
import { MyData} from './mydata';
import { ActivatedRoute } from '@angular/router';
import { OtherService } from './other.service';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Headers, RequestOptions } from '@angular/http';
import { ParameterService } from '../parameter.service';
import { LocalStorageService } from 'angular-2-local-storage';
@Component({
templateUrl: 'app/test/test.component.html'
})
export class TestComponent implements OnInit {
subscription: any;
customerId: string;
// set getter as a property on the variable `year`:
////year: string;
get year(): string {
console.log("test.component.get()");
const value = this._parameterService.p['year'] + "";
// Any other code you need to execute when the data is changed here
this.getDataFromApi();
return value;
}
private sub: any;
errorMessage: string;
data: MyData[];
constructor(private _otherService: OtherService,
private _parameterService: ParameterService,
private _route: ActivatedRoute,
private _localStorageService: LocalStorageService) { }
getDataFromApi() {
// store route parameters in Local Storage
// if none found, try reading from Local Storage
if (this.customerId == null)
this.customerId = this._localStorageService.get('customerId') + "";
//if (this.year== null)
// this.year = this._localStorageService.get('year') + "";
this._localStorageService.set('customerId', this.customerId);
//this._localStorageService.set('year', this.year);
// try getting YEAR (not customerId, yet) from getter
this._otherService.getDataFromApi(this.customerId, this.year)
.then(
data => this.data = data,
error => this.errorMessage = <any>error);
}
getData(): void{
this.data = this._otherService.getData();
}
resetComponentState(): void {
this.getDataFromApi();
}
ngOnInit(): void {
this.sub = this._route.params.subscribe(params => {
this.customerId = params['customerId'];
//this.year = params['year'];
this.resetComponentState(); // based on new parameter this time
});
}
}
1 ответ
Используйте геттеры и сеттеры. Что-то вроде этого:
// get global value
get year() {
const value = this._parameterService.p['year'];
// Any other code you need to execute when the data is changed here
this.getDataFromApi();
return value;
}
set year(value) {
this._parameterService.p['year'] = value;
}
У меня есть запись в блоге об этом здесь: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/
И плункер здесь: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview