我有一个简单的结构,具有多个组件和单个服务[StackBlitz]:
@Injectable()
export class Service {
constructor(private http: HttpClient) {}
post(entity: IEntity): Observable<IEntity> {
return this.http
.post<IEntity>('/api/entity', entity)
.pipe(map(parseDates));
}
get(): Observable<IEntity[]> {
return this.http
.get<IEntity[]>('/api/entity')
.pipe(map(parseDates));
}
}
@Component({
selector: 'app-component0',
template: `<app-component1></app-component1>
<app-component2></app-component2>`,
styleUrls: []
})
export class Component0 {}
@Component({
selector: 'app-component1-create',
template: `<button (click)="submit()">Submit</button>`,
styleUrls: []
})
export class Component1 {
constructor(private service: Service) { }
submit() {
this.service.post({foo: 'bar'})
.subscribe(console.info, console.error)
}
}
@Component({
selector: 'app-component2-table',
template: `<pre>{{ entities | json }}</pre>`,
styleUrls: []
})
export class Component2 implements OnInit {
entities: IEntity[];
constructor(private service: Service) { }
ngOnInit() {
this.service.get()
.subscribe(entities => this.entities = entities,
console.error)
}
}
如何通过Component1
让Component2
更新Service
?
答案 0 :(得分:1)
您应该另外观察一下,以减轻组件之间的交流:
@Injectable()
export class StoreService {
private _employes$ = new BehaviorSubject<{id:number,employee_name:string,employee_salary:number,employee_age:number}[]>([]);
constructor(private _http: HttpClient) {
this.refresh();
}
refresh() {
this._http.get<{id:number,employee_name:string,employee_salary:number,employee_age:number}[]>('https://dummy.restapiexample.com/api/v1/employees').subscribe(
data => this._employes$.next(data)
);
}
post() {
const payload = {"name":"test","salary":"123","age":"23"};
this._http.post('https://dummy.restapiexample.com/api/v1/create', payload).subscribe(() => {
this.refresh();
})
}
get employes$(): Observable<{id:number,employee_name:string,employee_salary:number,employee_age:number}[]> {
return this._employes$.asObservable();
}
}
由两部分组成:
商店可观察的用途,当您要更新流时,可以在其旁边。
private _employes$ = new BehaviorSubject<{...}[]>([]);
暴露的吸气剂。需要通过商店中的任何更改通知的任何组件都可以订阅。
get employes$(): Observable<{...}[]> {
return this._employes$.asObservable();
}
从现在开始,所有内容都与您的实际情况有关,您可以通过多种方式来更新此内部可观察到的内容:
最快的方法:
refresh() {
this._http.get<{...}[]>('...').subscribe(
data => this._employes$.next(data)
);
}
在您的服务内部,您订阅了http呼叫并更新了内部可观察的内容。
专业版:
骗局:
可观察的体操
如果您不想订阅您的服务。您可以执行以下操作:
return this._http.get<{...}[]>('...')
.pipe(switchMap(result => {
this._employes$.next(result);
return this.employes$;
}));
您将您的http可观察者转换为内部可观察者。同时,您接下来将获得API答案的新结果。
如果明天您需要在API响应中委派特殊特征,然后才能在整个应用程序中使用它。
您可以:
refresh(myCustomTraitment: = null) {
return this._http.get<{...}[]>('...')
.pipe(switchMap(result => {
if (myCustomTraitment) {
result = result.map(myCustomTraitment);
}
this._employes$.next(result);
return this._employes$;
}));
}