typescript - HTTP og nestede objekter (Angular2 RC1 + TS)
Jeg har problemer med å vise dataene mine i nettleseren. For å forklare problemet mitt bruker jeg litt dummy-kode. Jeg har noen innlagte objekter som forårsaker problemet mitt. Her vil jeg vise ett innlagt objekt for å vise problemet mitt.
Først og fremst gjør jeg bare HTTP-kall for Car-objektet. Så saveCar fungerer også som å oppdatere bilen, avhengig av hva brukeren gjør i appen. Alle metodene i tjenesten fungerer som de skal.
Så tjenesten min ser omtrent slik ut:
@Injectable()
export class Service {
constructor(private http: Http) { }
saveCar(car: Car) {
return this.http.post ....
}
getCars(){
return this.http.get...
}
getById(id: string) {
return this.http.get...
}
}
Da har jeg en Car-klasse, hvor det nestede objektet «Brand» kommer inn i bildet. Brand har da sin egen klasse, men jeg vil utelate den.
export class Car {
private brands: Array<Brand>;
constructor(public id: string, public name: string) {
this.brands = new Array<Brand>();
}
public getBrands(): Array<Brand> {
return this.brands;
}
public addBrand(value: Brand): void {
this.brands.push(value);
}
//some other methods.
}
Så har jeg en liste-komponent som lister alle biler, dette fungerer som det skal!
@Component({
selector: 'car-list',
template: `
<h1>Add Car</h1>
<form (submit)="saveCar()">
<input required [(ngModel)]="name" placeholder="Add car">
</form>
<br>
<table>
<tr *ngFor="let car of cars" >
<td>{{car.name}}</td>
<td><button (click)="goToDetail(car)">Detail</button></td>
</tr>
</table>
`,
})
export class ListComponent implements OnActivate {
id: string
name: string;
cars: Array<Car>
constructor(public _service: Service, public _router: Router) { }
routerOnActivate(): void {
this._service.getCars()
.subscribe(cars => this.cars = cars);
}
saveCar() {
let car = new Car(this.id, this.name)
this._service.saveCar(Car)
.subscribe(car => this.cars.push(car));
this._service.getCars()//
.subscribe(cars => this.cars = cars);
}
goToDetail(car:Car) {
this._router.navigate(['/cardetail', car.id]);
}
}
Problemet jeg har er i detaljkomponenten, hvor brukeren blir navigert etter å ha klikket på en spesifikk bil. Rutingen og henting av bilen fra databasen fungerer som den skal. Det vet jeg, fordi hvis jeg fjerner hele malen bortsett fra <h1>Bil: {{car?.name}}</h1>, blir navnet skrevet ut riktig med elvis-operatoren.
Men detaljkomponenten min ser omtrent slik ut:
@Component({
selector: 'car-detail',
template: `
<h1>Car: {{car?.name}}</h1>
<hr>
<button (click)="addBrand()">Add Brand</button>
<div *ngFor="let brand of car.getBrands(); let i=index">
<h2>Brand {{i+1}}</h2>
</div>
`,
})
export class DetailComponent implements OnActivate {
@Input() car: Car;
constructor(public _service: Service, public _router: Router) { }
routerOnActivate(curr: RouteSegment): void {
let id = curr.getParam('id');
this._service.getById(id)
.subscribe(car => {
this.car = car;
});
}
addBrand() {
this.car.getBrands().push(new Brand());
}
//some other methods
}
Så i detaljkomponenten min kaller jeg alle metodene slik: car.someMethod() og videre på det nestede Brand-objektet slik: brand.someMethod() i malen. Så feilen kommer ved kall av metoden, for eksempel i malen 'kan ikke hente getBrands av undefined'. Jeg har prøvd å bruke elvis-operatoren slik: car?.getBrands(). Det fungerer ikke. Jeg har prøvd å pakke hele greien inn i en div, både med elvis-operatoren og en <div *ngIf="car"></div>, det fungerer ikke. Har til og med prøvd med <template *ngIf="car"></template>, vel, det fungerer heller ikke....
Rediger: min feil, innpakking som nedenfor, det fungerer på en måte, altså, det gir en ny feil....
Mal :
@Component({
selector: 'car-detail',
template: `
<h1>Car: {{car?.name}}</h1>
<hr>
<button (click)="addBrand()">Add Brand</button>
<div *ngIf="car">
<div *ngFor="let brand of car.getBrands(); let i=index">
<h2>Brand {{i+1}}</h2>
</div>
</div>
Svar #1
Du nevner <h1>Car: {{car?.name}}</h1> med ?, men hele kodeeksemplet har <td>{{car.name}}</td> uten ?, noe som vil forårsake en feil.
<div *ngFor="let brand of car.getBrands(); let i=index">
trenger også en ? for å unngå feil når Angular prøver å rendre visningen og car ennå ikke er satt
<div *ngFor="let brand of car?.getBrands(); let i=index">
