【问题标题】:How to get async data which is stored in the service?如何获取存储在服务中的异步数据?
【发布时间】:2017-10-03 03:56:01
【问题描述】:

我正在从 http 获取数据,将其存储在同一服务中的数组中。

export class UserService {
    myusers: User[];
    constructor(private http: HttpClient) {}
    getUsers () {
     return this.http.get<User[]>('https://randomuser.me/api/results=5')
    .subscribe( data => { this.myusers = data['results']}); }
}

当我在 component.ts 中控制台我的用户时,它会打印“未定义”。

export class UserComponent implements OnInit {
  constructor(private service: UserService) { }
  ngOnInit() {
    this.service.getUsers();
    console.log(this.service.myusers); //undefined
  }
}

那么我如何访问this.service.myusers?不要建议将数据存储在组件数组而不是服务 myusers 数组中的解决方案。

【问题讨论】:

  • 请查看 rxjs 的文档。阅读 observables 和 promise。您的数据是异步的。 .你不能指望服务在你调用它时返回值,所以你应该在你的服务中返回 Observable 并在你的组件中订阅它。
  • 所以没有办法在服务中存储数据(数组)?但我认为这是一个好方法,因为我也可以在其他组件中使用这个数组,而无需再次调用 http.get()。

标签: angular typescript angular4-httpclient


【解决方案1】:

你总是可以使用 Observable.of 从数组中返回一个 Observable

valores=[{id:1,nombre:"uno"},{id:2,nombre:"dos"},{id:3,nombre:"tres"}];

getUsers()
{ 
    if (this.valores)
       return Observable.of(this.valores);
    else 
        return this.http.get(url).map((response)=>
        this.valores=...
        ...);
}

【讨论】:

    【解决方案2】:

    由于从 API 返回数据需要一些时间,因此您需要从服务中回调有关作业的完成情况。

    export class UserService {
        myusers: User[];
        constructor(private http: HttpClient) {}
        getUsers () {
            return this.http.get<User[]>('https://randomuser.me/api/results=5');
        }
        setUsers (users: User[]) {
            this.myusers = users;
        }
    }
    

    如下调用函数:

    export class UserComponent implements OnInit {
      constructor(private service: UserService) { }
      ngOnInit() {
        this.service.getUsers()
        .subscribe( data => { this.service.setUsers(data); console.log(data); });
      }
    }
    

    如果这不符合您的目的,请告诉我

    【讨论】:

    • 这满足了我的条件。用于创建列表 *ngFor = "let user of service.myusers"。这是一个好方法吗?
    • 从您上面的评论中我可以理解,您可以采用缓存方法来避免多次调用同一请求。一种好的方法是始终要求服务获取详细信息,然后服务通过调用 API 来决定是返回缓存响应还是新响应
    【解决方案3】:

    你的服务应该是这样的。

        import {Injectable} from '@angular/core';
        import {Http, Response} from '@angular/http';
        import {Observable} from 'rxjs/Observable';
    
        @Injectable()
    
        export class UserService {
            constructor(private http: Http) {}
    
            getUsers (): Observable<void> {
                const url = 'https://randomuser.me/api/results=5';
                return this.http.get(url).map(
                    (res: Response) => {
                      return res.json() as = User[];
                    }).catch(
                    (error: Response) => {
                        return Observable.throw(error.json());
                    });
            }
        }
    

    组件应该是这样的

    export class UserComponent implements OnInit {
      users: User[] = [];
    
      constructor(private userService: UserService) { }
    
      ngOnInit() {
        this.getUsers();
      }
    
      private getUsers(): void {
           this.userService.getUsers().subscribe(
             (response: User[]) => {
               this.users = response;
               console.log(response); 
            );
        }       
    }
    

    注意:angular4 基于类型脚本。因此,根据最佳实践,您需要将类型分配给方法和变量。

    【讨论】:

    • 感谢您的解决方案,但它不会将数据保存在 service myusers 数组中。
    • 检查我的答案。如果您愿意,请随时发布您完成的解决方案
    猜你喜欢
    • 2016-01-21
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2017-11-04
    • 2017-06-29
    相关资源
    最近更新 更多