Свойства в Observable не найдены при привязке к шаблону - PullRequest
1 голос
/ 02 апреля 2020

Я вызываю данные из состояния NGXS, которое, когда я console.log() показывает, присутствует в форме интерфейса, используемого для его описания. Есть свойство items, представляющее собой массив из 3 объектов, которые я хочу перебрать в моем шаблоне. Однако, когда я нацеливаюсь на свойство items, я получаю сообщение об ошибке в vsCode, в котором говорится, что свойство этого типа не существует и на экране ничего не отображается.

Моя модель состояния выглядит следующим образом

export interface CattegoryIndexItem{
    cattegory: string;
    products: ProductIndexListItem[];
}

export interface ProductIndexListModel{ items: CattegoryIndexItem[]; }

мой компонент выглядит следующим образом

export class ProductPageComponent implements OnInit {

  @Select() productIndexState$: Observable<ProductIndexListModel>;

  constructor(private store: Store) {}

  ngOnInit(): void {
    this.store.dispatch(new GetProductIndexList());

  }

  showData(){
    this.productIndexState$.subscribe(res => console.log(res));
  }

}

внутри моего шаблона

<article *ngFor="let item of productIndexState$.items | async">
    <p>{{item.cattegory}}</p>
</article>

<button (click)="showData()">click</button>

Когда страница загружается, я получаю эту ошибку

Ошибка TS2339: Свойство 'items' не существует в типе 'Observable'.

У меня никогда не было этой проблемы при работе с observables, есть ли что-то, что делает NGXS, чтобы нам нужно было обращаться к нему по-другому?

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Рад, что данный ответ уже помогает.

Я хотел бы ответить на ваш комментарий здесь, чтобы добавить к этому ответу.

Вы спросили: Теперь, что делает это возможным ?

Теперь происходит следующее:

Ваш метод showData () вызывает подписку на саму наблюдаемую и разворачивает ее. Это должно иметь структуру вашего интерфейса. Этот интерфейс затем имеет свойство items.

Ваш асин c канал в вашем шаблоне

<article *ngFor="let item of productIndexState$.items | async">
    <p>{{item.cattegory}}</p>
</article>

на другом сайте не предназначен для самой наблюдаемой, но для свойства items. Это еще не существует здесь и также не является действительной наблюдаемой, которую может обработать asyn c.

asyn c труба Angular работает аналогично подписке в showData (). Он берет все, что находится внутри наблюдаемой, и делает его доступным для обработки.

То, что сделал @Garth Mason в своем ответе, вызывало asyn c на наблюдаемой первой, чтобы «развернуть» его и использовать псевдоним * 1024. * как , чтобы дать ему правильное имя (без знака $). Развернутый объект содержит искомые элементы, которые теперь можно перебирать с помощью ngfor.

Его код снова для лучшей справки:

<ng-container *ngIf="productIndexState$ | async as productIndexState">
    <article *ngFor="let item of productIndexState.items">
        <p>{{item.cattegory}}</p>
    </article>

    <button (click)="showData()">click</button>
</ng-container>

Просто дополнительный комментарий к контейнеру ng оборачивая тэг Angular допускает только одну директиву , например, ngFor или ngIf для тега. Поэтому всякий раз, когда вам нужно выполнить два "Angular шага процесса" в вашем шаблоне, вам нужно что-то сделать для первого шага ( контейнер ng здесь ), а затем ваши фактические теги (), которые выполняют второй шаг. Контейнер ng не имеет разметки и поэтому не виден в вашем HTML. Вот почему идеально оборачивать такие шаги обработки; -)

1 голос
/ 02 апреля 2020

Выглядит как сбой в синтаксисе шаблона - нельзя вызвать .items для самого Observable, вы хотите вызвать его для объекта, испускаемого этим Observable.

Так что вам нужно передать Observable через async сначала например

<ng-container *ngIf="productIndexState$ | async as productIndexState">
    <article *ngFor="let item of productIndexState.items">
        <p>{{item.cattegory}}</p>
    </article>

    <button (click)="showData()">click</button>
</ng-container>
...