基本上作为标题陈述,我需要返回多个observable或者结果。目标基本上是加载让我们说库列表,然后根据该库ID加载书籍。我不想在组件中调用服务,而是希望在页面加载之前加载所有数据。
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { UserService } from './../_services/index';
@Injectable()
export class LibraryResolver implements Resolve<any> {
constructor(private _userService: UserService) {}
resolve(route: ActivatedRouteSnapshot) {
return this._userService.getLibraryList();
}
}
如何首先加载库列表,然后为每个库加载书籍信息并返回到我的组件?
PS:我的服务通过Id
加载此方法this.userService.getLibraryBooks(this.library["id"]).subscribe((response) => {
...
答案 0 :(得分:3)
我找到了解决该问题的方法,也许会对某人有所帮助,所以基本上我已经使用forkJoin
来组合多个Observable并解决所有问题。
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]
};
});
};
现在,它可以按预期正常工作。
答案 1 :(得分:2)
您可以使用withLatestFrom
轻松解析多个可观察物。
这是Stackblitz中的有效演示:https://stackblitz.com/edit/angular-xfd5xx
下面的解决方案。
在您的解析器中,使用withLatestFrom
合并您的可观察对象:
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 { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LibraryDisplayComponent } from './library-display.component';
import { LibraryDisplayResolver } from '../resolvers/library-display.resolver';
const routes: Routes = [
{
path: ':id',
component: LibraryDisplayComponent,
resolve: {
libraryResolverData: LibraryDisplayResolver
}
},
{
path: '',
redirectTo: '1',
pathMatch: 'full'
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class LibraryDisplayRoutingModule { }
在接收组件中,您可以像这样访问两个可观察对象的快照:
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];
}
}
答案 2 :(得分:0)
我有类似的情况,但我的处理方式略有不同。
在您的情况下,我的理解是您希望获取查询参数,然后根据响应调用更多服务。
我这样做的方法是让一个组件包裹其他组件,并传递他们需要的对象。我通过路由paramMap订阅它们然后将所有其他调用包装在一个。 Observalbe.forkJoin
在我的包装器组件中,我执行以下操作:
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;
}
);
}
});
不完全是你所追求的,但我希望它指出你正确的方向
答案 3 :(得分:0)
我建议你使用Observables,它们会让你的生活变得轻松。 请查看这两篇文章,了解有关如何使用observable实现该目标的更多详细信息:
http://www.syntaxsuccess.com/viewarticle/combining-multiple-rxjs-streams-in-angular-2.0
http://blog.danieleghidoli.it/2016/10/22/http-rxjs-observables-angular/
我个人使用flatMap
祝你好运。