簡體   English   中英

如何解決`(logList: string[]) =&gt; void&#39;不能分配給&#39;(value: string[], index: number) =&gt; ObservableInput類型的參數<any> `?

[英]How to solve `(logList: string[]) => void' is not assignable to parameter of type '(value: string[], index: number) => ObservableInput<any>`?

我有一個問題,要從兩個 observable 中創建一個 observable 對象並保持第一個 observable 的順序。 正如您在示例中看到的,目標是按日期對可觀察對象進行排序。

看起來問題出在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順序不正確的問題。

我已經嘗試並搜索了很多,但是一天多之后,我找不到任何可以擺脫此錯誤消息的方法。 奇怪的是,即使有這個錯誤,它有時也會編譯,然后結果是正確的。

concatMap使用return也不起作用 => 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;
        })
      );
  }
}

應用程序組件.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>

日志.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);
    }
  }
}

日期.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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM