基于Angular 4的服务检索单值的模式

时间:2017-07-10 00:05:38

标签: javascript c# angular asp.net-web-api

我正在尝试构建基于Angular 4的服务(由基于C#的RESTful API支持),该服务允许存储和检索Web应用程序范围的设置。像所有常见应用程序设置的基于键值对的查找。

这个想法是这样的:

  1. 从基于C#WebApi的RESTful服务检索应用程序启动时的所有设置到客户端JavaScript数组并存储在Angular 4服务中。
  2. 如果需要任何特定设置,请首先查看本地检索到的数组以获取所述设置并返回该设置。
  3. 如果未找到所述设置,请调用前面提到的特定设置的WebAPI服务以查看它是否可用并检索该设置。另外,在客户端阵列中推送检索到的设置,这样我就不必再次拨打电话了。
  4. 我遇到的问题是:

    我想返回一个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();
        }
    }
    

2 个答案:

答案 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); 

您可以向用户显示错误消息,也可以根据您的网站要求将其视为空白。