InvalidPipeArgument: '' для канала 'AsyncPipe' - PullRequest
0 голосов
/ 29 октября 2019
  timers: Observable<ITimer>[]=[];

Шаблон:

<div *ngFor="let item of timers | async">
  {{ item.time }}
  <div (click)="remove(item.index)">Remove</div>
</div>

Почему я получаю эту ошибку?

Если не инициализировать this.timers, то работает асинхронный режим. В противном случае я не могу получить длину в этом методе:

 add() {
    let options = {
      finishDate: null,
      time: null,
      index: this.timers.length
    };

    this.timers.push(this.create(options));

  }

В строке: index: this.timers.length

1 Ответ

0 голосов
/ 29 октября 2019

Из Angular Docs на трубе async:

Труба async подписывается на Observable или Promise ивозвращает последнее значение, которое он испустил. Когда создается новое значение, канал async отмечает компонент, который необходимо проверить на наличие изменений. Когда компонент уничтожается, async передается unsubscribe автоматически, чтобы избежать возможных утечек памяти.

Но из вашего объявления свойства кажется, что это Array. Так что это не сработает.

Не инициализируйте здесь свойство timers и измените тип timers на Observable<ITimer[]>

Примерно так:

timers: Observable<ITimer[]>;

Теперь это будет зависеть от того, как вы инициализируете свойство timers. Тем не менее, убедитесь, что это Observable

ОБНОВЛЕНИЕ:

В зависимости от вашего варианта использования, вы можете сделать это в виде массива Observable с. Что у вас уже есть.

timers: Observable<ITimer>[]=[];

Вы просто используете трубу async в неправильном месте. Попробуйте это:

<div *ngFor="let item$ of timers">
  <div *ngIf="(item$ | async) as item">
    {{ item.time }}
    <div (click)="remove(item.index)">Remove</div>
  </div>
</div>

Вот Рабочий образец StackBlitz для вашей ссылки.

В качестве альтернативы

Вы также можете создать BehaviorSubject>:

timersArray: ITimer[] = [];
timers$: BehaviorSubject<Array<ITimer>> = new BehaviorSubject<Array<ITimer>>(this.timersArray);

А затем при добавлении вы можете сначала обновить timersArray, а затем обновить поток BehaviorSubject, вызвав nextметод timers$:

add() {
  let options = {
    finishDate: null,
    time: new Date(),
    index: this.timers.length
  };
  this.timers.push(this.create(options));
  this.timersArray.push(options);
  this.timers$.next(this.timersArray);
}

И тогда вы можете использовать это в своем шаблоне:

<div *ngFor="let item of (timers$ | async)">
  {{ item.time }}
  <button (click)="remove(item.index)">Remove</button>
</div>

Вот Обновлен StackBlitz для вашей ссылки.

...