Я следую HeroTutorial , но использую бэкэнд Django.У меня есть Hero
объект, который я получаю от конечной точки DRF (проверено почтальоном).В моем hero-detail.html hero.name
и hero.id
ничего не отображается.
Я знаю, что объект hero
передается в hero-detail.html , потому что браузер показывает "Details" и "id:", поэтому строка <div *ngIf="hero">
говоритмне, что есть hero
..
Но если есть hero
, почему hero.name
ничего не показывает?
В консоли браузера нет ошибок.Ссылка на hero-detail.component исходит от dashboard.component , который использует тот же метод, но по какой-то причине hero.name
и hero.number
работают нормально. dashboard.component.html отображается правильно, поэтому я знаю, что мои службы работают нормально.
Мой hero-detail.html
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.number}}</div>
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name">
</label>
</div>
</div>
<button (click)="goBack()">go back</button>
hero-detail.component
import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero'
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.scss']
})
export class HeroDetailComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private heroService: HeroService,
private location: Location
) {}
@Input() hero: Hero;
ngOnInit(): void {
this.getHero();
}
getHero(): void {
const number = +this.route.snapshot.paramMap.get('number');
this.heroService.getHero(number)
.subscribe(hero => this.hero = hero);
}
goBack(): void {
this.location.back();
}
}
dashboard.component
import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [ './dashboard.component.scss' ]
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService) { }
ngOnInit() {
this.getHeroes();
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes.slice(1, 5));
}
}
dashboard.html
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" class="col-1-4"
routerLink="/detail/{{hero.number}}">
<div class="module hero">
<h1>{{hero.name}}</h1>
</div>
</a>
</div>
hero.service
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { Observable, of } from 'rxjs'
import { HttpClient, HttpHeaders } from '@angular/common/http'
import { catchError, map, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class HeroService {
private heroesUrl = 'http://127.0.0.1:8000/heroes/'; // URL to web api
constructor(
private http : HttpClient
) { }
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
}
getHero(number:number): Observable<Hero>{
return this.http.get<Hero>(`${this.heroesUrl}${number}`);
}
// getHero(number: number): Observable<Hero> {
// return of(HEROES.find(hero => hero.number === number));
//}
}
hero.service ответ конечной точки от localhost:8000/heroes/2
, полученный от Почтальона:
[
{
"name": "better hero",
"number": 2
}
]
также hero.service ответ конечной точки от localhost:8000/heroes
, полученный от Почтальона:
[
{
"name": "bad hero",
"number": 7
},
{
"name": "bad hero",
"number": 7
},
{
"name": "better hero",
"number": 2
}
]
views.py
class HeroList(generics.ListAPIView):
queryset = Hero.objects.all()
serializer_class = HeroSerializer
class Meta:
model = Hero
fields = ('number', 'name')
class HeroDetail(generics.GenericAPIView):
serializer_class = HeroSerializer
#TODO why do i need many=True here, this should returning one instance
def get(self, request, number):
# number = self.request.query_params.get('number')
hero_detail = Hero.objects.filter(number=number)
serializer = HeroSerializer(hero_detail, many=True)
return Response(serializer.data)
class Meta:
model = Hero
fields = ('number', 'name')