typescript - HTTP és beágyazott objektumok (Angular2 RC1 + TS)
Néhány problémám van az adataim böngészőben történő megjelenítésével. A problémám elmagyarázásához némi tesztkódot használok. Vannak beágyazott objektumok, amelyek problémát okoznak. Itt meg fogok jeleníteni egy beágyazott objektumot, hogy bemutassam a problémámat.
Először is, csak a Car-objektumhoz csinálok http hívásokat. Tehát a saveCar úgy működik, mintha a kocsit is frissítené, attól függően, hogy a felhasználó mit csinál az alkalmazásban. Az összes metódus a szolgáltatásban úgy működik, ahogy kell.
Tehát a szolgáltatásom valahogy így néz ki:
@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...
}
}
Akkor van egy Car osztályom, ahol a beágyazott "Brand" objektum lép működésbe, a Brand-nek ezután megvan a saját osztálya, de azt kihagyom.
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.
}
Akkor van egy lista-komponensem, ami felsorolja az összes autót, és ez úgy működik, ahogy kell!
@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]);
}
}
A problémám a detail-komponensben van, ahol a felhasználót egy adott autóra kattintás után navigálják. Az útvonalkezelés és az autó lekérése az adatbázisból úgy működik, ahogy kell. Ezt azért tudom, mert ha az összes sablont eltávolítom, kivéve a <h1>Autó: {{car?.name}}</h1> részt, a név rendben megjelenik az Elvis-operátorral.
De a részlet-komponensem valahogy így néz ki:
@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
}
Tehát a detail komponensemben minden metódust így hívok: car.someMethod(), és tovább a beágyazott Brand objektumon keresztül így: brand.someMethod() a sablonban. Tehát a hiba a metódus hívásakor jelentkezik, például a sablonban: 'cannot get getBrands of undefined'. Megpróbáltam az elvis operátort így használni: car?.getBrands(). Nem működik. Megpróbáltam az egészet egy divbe csomagolni, mind az elvis operátorral, mind így: <div *ngIf="car"></div>, de nem működik. Még próbáltam <template *ngIf="car"></template>-t is, nos az sem működik....
Szerkesztés: az én hibám, az alábbi módon csomagolva, "félig" működik, azaz új hibát ad....
Sablon :
@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>
Válasz #1
Megemlíted a <h1>Car: {{car?.name}}</h1>-t a ?-vel, de a teljes kódpélda a <td>{{car.name}}</td>-t tartalmazza ? nélkül, ami hibát fog okozni.
<div *ngFor="let brand of car.getBrands(); let i=index">
szüksége van egy ?-re is, hogy elkerülje a hibákat, amikor az Angular megpróbálja renderelni a nézetet, és a car még nincs beállítva
<div *ngFor="let brand of car?.getBrands(); let i=index">
