Angular 角度4如何在分解器中返回多个观察值

Angular 角度4如何在分解器中返回多个观察值,angular,angular-routing,angular-http,angular-httpclient,Angular,Angular Routing,Angular Http,Angular Httpclient,正如标题所述,我需要返回多个观测值,或者可能是结果。目标基本上是加载一个库列表,然后基于该库ID加载书籍。我不想在组件中调用服务,而是希望在页面加载之前加载所有数据 从'@angular/core'导入{Injectable}; 从'@angular/router'导入{Resolve,ActivatedRouteSnapshot}; 从“/../\u services/index”导入{UserService}; @可注射() 导出类LibraryResolver实现解析{ 构造函数(私有_u

正如标题所述,我需要返回多个观测值,或者可能是结果。目标基本上是加载一个库列表,然后基于该库ID加载书籍。我不想在组件中调用服务,而是希望在页面加载之前加载所有数据

从'@angular/core'导入{Injectable};
从'@angular/router'导入{Resolve,ActivatedRouteSnapshot};
从“/../\u services/index”导入{UserService};
@可注射()
导出类LibraryResolver实现解析{
构造函数(私有_userService:userService){}
解析(路由:ActivatedRouteSnapshot){
返回此项。_userService.getLibraryList();
}
}
如何先加载库列表,然后加载每个库的图书信息并返回到组件

PS:我的服务通过Id加载此方法

this.userService.getLibraryBooks(this.library[“id”])。订阅((响应)=>{
//响应处理
})

我也有类似的情况,但我的处理方式略有不同

在您的情况下,我的理解是您希望获得查询参数,然后根据响应调用更多的服务

我这样做的方式是让一个组件包裹其他组件,并传递它们需要的对象。我通过route paramMap订阅这些电话,然后将所有其他电话都打包成一个。观察者,观察者

在我的包装器组件中,我执行以下操作:

ngOnInit() {

    this.route.params.subscribe((params) => {
        if (params.hasOwnProperty('id') && params['id'] != '') {
            const slug = params['slug'];
            Observable.forkJoin([
                this.myService.getData(id),
                this.myService.getOtherData(id),
            ]).subscribe(
                ([data, otherData]) => {
                    this.data = data;
                    this.otherData = otherData;
                },
                error => {
                    console.log('An error occurred:', error);
                },
                () => {
                    this.loading = false;
                }
                );
        }
    });

不完全是你所追求的,但我希望它能为你指明正确的方向。我建议你使用可观察的东西,它们会让你的生活轻松很多。 查看这两篇文章,了解如何使用可观测数据实现这一目标的更多详细信息:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Library } from '../models/library.model';
import { LibraryBook } from '../models/library-book.model';
import { LibraryService } from '../services/library.service';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';

@Injectable()
export class LibraryDisplayResolver implements Resolve<[Library, LibraryBook[]]> {

  constructor(
    private _libraryService: LibraryService,
  ) { }

  resolve (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<[Library, LibraryBook[]]> {
    const libraryId = route.params['id'];
    return this._libraryService.getLibrary(libraryId).pipe(
      withLatestFrom(
        this._libraryService.getBooksFromLibrary(libraryId)
      )
    );
  }
}

我个人使用
flatMap


祝您好运。

您可以使用
和最新from
轻松解析多个观测值

下面是Stackblitz中的一个工作演示:

解决方案如下

在您的解析器中,使用
和latestfrom
组合您的观测值:

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Library } from '../models/library.model';
import { LibraryBook } from '../models/library-book.model';
import { LibraryService } from '../services/library.service';
import { Observable } from 'rxjs';
import { withLatestFrom } from 'rxjs/operators';

@Injectable()
export class LibraryDisplayResolver implements Resolve<[Library, LibraryBook[]]> {

  constructor(
    private _libraryService: LibraryService,
  ) { }

  resolve (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<[Library, LibraryBook[]]> {
    const libraryId = route.params['id'];
    return this._libraryService.getLibrary(libraryId).pipe(
      withLatestFrom(
        this._libraryService.getBooksFromLibrary(libraryId)
      )
    );
  }
}
在接收组件中,您可以访问两个观察对象的快照,如下所示:

import { Component, OnInit } from '@angular/core';
import { LibraryBook } from '../models/library-book.model';
import { Library } from '../models/library.model';
import { ActivatedRoute } from '@angular/router';

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'library-display',
  templateUrl: './library-display.component.html',
  styleUrls: ['./library-display.component.scss']
})
export class LibraryDisplayComponent implements OnInit {

  library: Library;
  libraryBooks: LibraryBook[];

  constructor(
    private route: ActivatedRoute
  ) { }

  ngOnInit() {
    this.library = this.route.snapshot.data['libraryResolverData'][0];
    this.libraryBooks = this.route.snapshot.data['libraryResolverData'][1];
  }
}

我为这个问题找到了一个解决方案,可能会对某些人有所帮助,所以基本上我使用了
forkJoin
来组合多个观测值并解决所有这些观测值

resolve(route: ActivatedRouteSnapshot): Observable<any> {
        return forkJoin([
                this._elementsService.getElementTypes(),
                this._elementsService.getDepartments()
                .catch(error => {

                    /* if(error.status === 404) {
                        this.router.navigate(['subscription-create']);
                    } */

                    return Observable.throw(error);
                })
        ]).map(result => {
            return {
                types: result[0],
                departments: result[1]
            };
        });
    };
resolve(路由:ActivatedRouteSnapshot):可观察{
返回叉连接([
此._elementsService.getElementTypes(),
这个._elementsService.getDepartments()
.catch(错误=>{
/*如果(error.status==404){
this.router.navigate(['subscription-create']);
} */
返回可观察抛出(错误);
})
]).map(结果=>{
返回{
类型:结果[0],
部门:结果[1]
};
});
};

现在它可以正常工作了。

如果您需要在加载组件之前提供数据,您可以在服务构造函数中实际执行HTTP调用。现在,当加载组件时,由于存在依赖项注入,服务对象将以所需的方式提供给组件data@VinodBhavnani谢谢,但我想用解析器解决这个问题谢谢,伙计,是的,这就是我要找的,感谢您的解决方案,但我希望有一种方法可以使用解析程序,因为我在这方面的知识还不够。对不起,我自己不使用它们!我已经在用observable了。这个主题是关于如何在解析器中使用多个一。你能举一个解析器的例子吗?在这个例子中,你可以获取一个,然后根据这个例子获取其他值?谢谢分享,但在测试了你的解决方案后,我意识到它并不总是能够解析所有数据,但它在第一次工作时是有效的。嗯,在我的应用程序中,它对我来说一直都很好(我只在那个用例中使用了这个模式)。我欢迎任何更正。添加了一个Stackblitz示例,仅供参考。希望您在否决投票之前进行回顾,我没有否决您,可能是其他人。您的回答实际上帮助了我的解决:)