Как использовать NgFor для одного элемента - PullRequest
0 голосов
/ 05 марта 2020

У меня есть следующий компонент, который получает ответ от моей службы, который выполняет вызов REST, следующим образом:

api.service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, ReplaySubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  url = 'api address';

  constructor(private http: HttpClient) { }

  getContent(){
    return this.http.get(this.url);
}
}

Ответ вернемся следующим образом:

{
    name: "intro1",
    course-content: "this is the content area"
}

content.component.ts

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service';
import { switchMap, map } from 'rxjs/operators';

@Component({
  selector: 'app-content',
  templateUrl: './content.component.html',
  styleUrls: ['./content.component.css']
})
export class ContentComponent implements OnInit {
  content;
  constructor(private api: ApiService) { }

  ngOnInit(){
    this.api.getContent().subscribe((res : any[]) => 
    {console.log(res[0])
    this.content = res[0];

)}}

Примечание: я тяну только один элемент [0] из ответа, но я не уверен, как правильно отображать данные в представлении content.component. Строка регистрируется в консоли, как требуется, и содержимое отображается в представлении, но я все еще получаю следующую ошибку:

cannot read property 'course-content' of undefined.

In 'old' AngularJS Я мог бы сослаться на это в представлении со следующим:

<p>{{content['course-content']}}</p>

, но я не могу сделать то же самое в 'new' Angular .

Ответы [ 4 ]

1 голос
/ 05 марта 2020

Метод getContent() в ApiService является асинхронным (HTTP GET вызов), это означает, что ваше свойство content будет undefined до завершения запроса.

Чтобы избежать доступа к course-content свойство content в случае, если content еще не определено, используйте синтаксис ngIf в шаблоне:

<p *ngIf="content">
  {{ content['course-content'] }}
</p>

Предложение для улучшения

Могу ли я предложить вам некоторые улучшения, набрав твоя модель

export interface Course {
  name: string,
  course-content: string 
}

Тогда ваш сервис должен быть таким, как показано ниже:

export class ApiService {
  ...

  getContent(): Observable<Course[]> {
    return this.http.get<Course[]>(this.url);
  }
}

Вы также можете использовать мощные Rx JS и Observables прямо внутри кода:

export class ContentComponent implements OnInit {
  content$: Observable<Course>;

  constructor(private api: ApiService) { }

  ngOnInit() {
    this.content$ = this.api.getContent().pipe(
      map(courses => {
        return (!courses || courses.length === 0) ? null : courses[0]; 
      })
    );
  } 

В вашем шаблоне:

  <p *ngIf="content$ | async as content">
    {{ content['course-content'] }}
  </p>
1 голос
/ 05 марта 2020

попробуйте добавить * ngIf: <p *ngIf="content">{{content['course-content']}}</p>

0 голосов
/ 05 марта 2020

Это зависит от сценария.

Если у this.content есть только один объект для каждого запроса, который вы можете написать напрямую, как показано ниже

изменить переменную content как content: any = {};

<p>{{ content.coursecontent }}</p>

, если this.content имеет более одного элемента, который вы можете написать следующим образом:

изменить переменную content как content: any = [ ];

<p *ngFor="let c of content">{{ c.course-content }}</p>

надеюсь, это сработает для вас.

0 голосов
/ 05 марта 2020

Я обычно использую интерфейсы для простого использования JSON объектов.

School.ts

export interface School {
    id: number,
    name: string,
    registrationCodeStudent: string,
    amountOfStudents: number
}

school.service.ts

schoolUrl: string = environment.apiEndpoint + "/school/";
getSchools(): Observable<School[]> {
    return this.http.get<School[]>(this.schoolUrl);
}

Итак, теперь я получил список школ, которые я могу использовать в моих файле component.ts или компоненте. html файлов.

Файл случайных компонентов

this.schoolService.getSchools().subscribe(schools => {
   this.schools = schools;
}, error => {
   this.handleError(error);
});

Случайный HTML файл

<div *ngFor="let school of schools"(click)="onSchoolSelected(school)">
    <p>{{ school.name }} ({{ school.amountOfStudents }})</p>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...