"全球" Angular 4中的服务(用于保存API调用)

时间:2017-07-27 12:25:09

标签: angular observable

如果标题与我的意思不符,请抱歉。我会尝试解释我想做的事情,也许有人可以告诉我一个更好的选择:

我想创建一个服务,从数据库中获取数据并将其存储在内部,因此不再需要调用API。例如,我希望服务获取某些对象的详细信息;对服务的第一次调用必须通过API获取数据,并将其存储在内部。因此,当我再次从其他组件调用该服务时,它不会调用API,但会返回存储的数据,从而大大减少了对API调用的需求。这可能吗?

我试过了,但它不起作用,它总是调用API:

(已编辑:完整服务类代码)

import { Injectable } from '@angular/core';

import { Http, Response, Headers } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class ObjectService {

  // We'll store the objects in this array
  private savedObjects : any;
  private objSubject = new Subject<any>();

  constructor(private http: Http) {
  }

  getObjects() : Observable<any> {

    const url = `http://URL_TO_API/objects`;

    if(!this.savedObjects || !this.savedObjects.length) {
      // We don't have any saved objects yet, make API call
      console.log("Getting the objects through API call");

      return this.http.get(url)
       .map(this.extractData) // Basically returns a JSON
       .map((objs) => { this.savedObjects = objs; return objs; } ) 
       .catch(this.handleError)
      ;
    }
    else {
      // Don't need to call the API
      console.log(["No API", this.savedObjects]);

      this.objSubject.next(this.savedObjects);

      return this.objSubject.asObservable();
    }
  }

  private extractData(res: Response) {
    //console.log("RECEIVED DATA: " + res.text());
    let body = res.json();

    return body || {};
  }


  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
        const body = error.json() || '';
        const err = body.error || JSON.stringify(body);
        errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
        errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return Observable.throw(errMsg);
  }

}

我只在AppComponent中提供服务,但我认为这并不意味着它是全球的&#39;对于所有组件......(我还在学习Angular 4,所以有些事情我不能完全理解)。

编辑: 我只在AppModule文件中提供了服务,但没有任何反应。

我从其他组件使用此服务的方式是:

(...)
import { ObjectService } from '../../services/object.service';

(...)

@Component({
  selector: 'app-target-container',
  templateUrl: './app-target-container.component.html',
  styleUrls: ['./app-target-container.component.css'],
  encapsulation: ViewEncapsulation.None,
  providers: []
})
export class AppTargetContainerComponent implements OnInit {

  constructor(protected objectService : ObjectService) {

  }

  ngOnInit() {

    // Get the objects
    this.objectService.getObjects().subscribe((objects: any) => {
        console.log(['Read objects: ', objects]);
        this.processObjects(objects);
    });

  }

  processObjects(objects : any) {
    // DO STUFF
  }
}

我一直在阅读有关ReplaySubject的一些文档,但我无法弄清楚如何将它们用于我需要的内容......任何人都可以推荐一本好的教程或书籍吗?

我怎么能这样做?提前谢谢,

2 个答案:

答案 0 :(得分:0)

将您的API服务添加到AppModule的提供者。

最简单的缓存是保存API路由,请求参数和响应(例如在ReplaySubject中)并返回先前执行的请求的响应。

如果您的API是用Graphql编写的,我建议使用包含API缓存的Apollo。

答案 1 :(得分:0)

仔细检查代码,我意识到我已经在兄弟组件中提供了服务以进行一些测试,我忘了以后删除它,所以Angular创建了一个新的服务实例,这就是数据不是的原因持久!

因此,只在AppCömponent(或AppModule)中提供ObjectService,它才能完美运行。

对失效感到抱歉:)