我有一个问题,要从两个可观察对象中创建一个可观察对象,并保持第一个可观察对象的顺序。在示例中可以看到,目标是按日期对可观察对象进行排序。
看来问题出在ngOnInit()
哪里,因为我在那儿得到错误concatMap(logList => {
:
TS2345: Argument of type '(logList: string[]) => void' is not assignable to parameter of type '(value: string[], index: number) => ObservableInput<any>'. Type 'void' is not assignable to type 'ObservableInput<any>'.
我正在使用,concatMap
因为否则有时我会遇到问题,即dailyLogs
顺序不正确。
我已经尝试了很多,但进行了很多搜索,但是经过一天多的时间,我找不到任何摆脱该错误消息的方法。奇怪的是,即使出现此错误,有时也会编译,然后结果是正确的。
另外return
在里面使用没用concatMap
=>return dailyLogs.push({logs: logList, date});
我究竟做错了什么?
以下是我的示例代码:
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
dailyLogs$: Observable<{logs: string[], date: Date}[]>;
constructor(
private readonly logService: LogService,
private readonly dateService: DateService
) {
}
ngOnInit(): void {
this.dailyLogs$ = this.dateService.getDates()
.pipe(
map(values => {
const dates = Array<Date>();
values.forEach(value => {
if (value) {
dates.push(value);
}
});
return dates;
}),
map(dates => {
const dailyLogs = Array<{logs: string[], date: Date}>();
dates.forEach(date => {
this.logService.findLogsByDate(date)
.pipe(
concatMap(logList => {
dailyLogs.push({logs: logList, date});
})
).subscribe();
});
return dailyLogs;
})
);
}
}
app.component.html
<ng-container *ngIf="dailyLogs$">
<div *ngFor="let i of [0, 1, 2]">
<table>
<tr>
<th>Logs</th>
</tr>
<tr *ngFor="let log of (dailyLogs$ | async)[i].logs">
<td>{{log}}</td>
</tr>
</table>
<br>
</div>
</ng-container>
log.service.ts
@Injectable({
providedIn: 'root'
})
export class LogService {
firstLogs = [
'Log 1',
'Log 2',
'Log 3',
'Log 4'
];
secondLogs = [
'Log 5',
'Log 6',
'Log 7',
'Log 8',
'Log 9',
'Log 10',
'Log 11'
];
thirdLogs = [
'Log 12',
'Log 13'
];
findLogsByDate(date: Date): Observable<string[]> {
const dateString = date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2);
if (dateString === '2019-12-17') {
return of(this.firstLogs);
} else if (dateString === '2019-12-16') {
return of(this.secondLogs);
} else if (dateString === '2019-12-13') {
return of(this.thirdLogs);
}
}
}
date.service.ts
@Injectable({
providedIn: 'root'
})
export class DateService {
firstDate = new Date('2019-12-17');
secondDate = new Date('2019-12-16');
thirdDate = null;
fourthDate = null;
fifthDate = new Date('2019-12-13');
getDates(): Observable<Date[]> {
return of([
this.firstDate,
this.secondDate,
this.thirdDate,
this.fourthDate,
this.fifthDate
]);
}
}
您不应该在map
函数内部订阅。尝试使用switchMap
并切换到一个Observable,将结果合并成一个新的Observable,如下所示:
ngOnInit(): void {
this.dailyLogs$ = this.dateService.getDates()
.pipe(
map(values => values.filter(value => !!value)), // User filter to get only truthy dates
switchMap(dates => combineLatest( // switch to a combined observable of all 'findLogsByDate' calls and map each to the desired output
dates.map(date => this.logService.findLogsByDate(date)
.pipe(
map(logList => ({logs: logList, date}))
)
)
))
);
}
这里工作的StackBlitz。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句