我正在尝试构建基于Angular 4的服务(由基于C#的RESTful API支持),该服务允许存储和检索Web应用程序范围的设置。像所有常见应用程序设置的基于键值对的查找。
这个想法是这样的:
我遇到的问题是:
我想返回一个Observable,即使我在本地拥有数组中的设置,这样我就可以处理Web应用程序必须等待检索设置的情况。
我还想处理针对特定设置的API调用失败的情况。
请参阅下文,了解我现在所拥有的任何帮助。
'use strict';
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { EmptyObservable } from 'rxjs/observable/EmptyObservable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/share';
import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { SettingAPIURLs } from '../global.urls';
import * as Interfaces from "../interfaces/models.interface";
import * as Classes from "../classes/models.classes";
@Injectable()
export class SettingsService {
private _settings: BehaviorSubject<Classes.Setting[]>;
private settingDataStore: {
settings: Classes.Setting[]
}
constructor(private http: Http) {
this.settingDataStore = { settings: [] }
}
loadSettings() {
this.http.get(SettingAPIURLs.GetSettings)
.map(response => response.json())
.subscribe(data => {
this.settingDataStore.settings = data;
this._settings.next(Object.assign({}, this.settingDataStore).settings);
}, error => {
console.log("There were errors in attempting to retrieve the web application's settings: " + error);
});
}
get CurrentSettings() {
return this._settings.asObservable().share();
}
retrieveSetting(SettingName: string): Observable<Classes.Setting> {
/*
I am lost as to what to do here.
*/
let returnedObservable: Observable<Classes.Setting> = new Observable<Classes.Setting>();
if (typeof (SettingName) === "undefined" || SettingName === null) {
return new EmptyObservable();
}
this.http.get(SettingAPIURLs.GetSetting + "?SettingName=" + SettingName)
.map(response => response.json())
.first();
}
}
答案 0 :(得分:0)
Angular为您的问题提供内置解决方案,称为resolve。本文介绍了如何使用它:
https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html
我们的想法是,在为页面运行逻辑之前,您已经加载了页面的数据。
基本的实现是你需要编写一个可以继续进行设置api调用的解析器。然后你只需要连接你的路由以开始使用解析器。
答案 1 :(得分:0)
如果我理解正确,你想发送设置,如果它存在,否则进行http调用。我假设您的设置对象是键值对对象。我不知道为什么你有一个阵列。
你可以做这样的事情
// extract fetch part separately . If settings exist return it or do http call
fetchSettings(){
return this._settings.asObservable
.flatMap(settings => settings ?
Observable.of(settings) :
this.http.get(SettingAPIURLs.GetSettings)
.map(response => response.json())
.do(data => {
this.settingDataStore.settings = data;
this._settings.next(
Object.assign(
{},
this.settingDataStore).settings);
})
.catch(error => {
console.log("..... " + error);
});
}
loadSettings(){
this.fetchSettings.subscribe(data => {
console.log('load Settings success', data);
});
}
retrieveSetting(SettingName: string): Observable<Classes.Setting> {
this.fetchSettings()
.flatMap(settings => settings[SettingName]?
Observable.of(settings[SettingName]) :
this.http.get(SettingAPIURLs.GetSetting +
"?SettingName=" + SettingName)
.map(response => response.json())
.do(res=> this._settings.value[SettingName] = res)
);
}
如果上述任何HTTP调用失败,您将获得一个异常,您可以在组件中处理这样的异常:
this.settingsService.retrieveSetting().subscribe(successFunction, failureFunction);
您可以向用户显示错误消息,也可以根据您的网站要求将其视为空白。