J'ai créé une très petite application pour récupérer des pays à partir d'un fichier json et le lier à la liste déroulante.
countries.json
export class Country {
id: number;
name: string;
}
factory.service.ts
import { Injectable } from '@angular/core';
import { Http, Response} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Country } from './shared/country';
@Injectable()
export class FactoryService {
private countryUrl = "app/data/countries.json";
constructor(private http: Http) {
}
getCountry(): Observable<any> {
return this.http.get(this.countryUrl)
.map(this.extractData)
.do(data => console.log("get Countries from json: " + JSON.stringify(data)))
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response.json();
return body || {};
}
private handleError(error: Response) {
console.log(error);
return Observable.throw(error.json().error || "500 internal server error");
}
}
factory-form.component.ts
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Factory } from './factory';
import { Country } from './shared/country';
import { FactoryService } from './factory.service';
@Component({
moduleId: module.id,
selector: 'factory-form',
templateUrl: './factory-form.component.html',
styleUrls: ['./factory-form.component.css'],
providers: [FactoryService]
})
export class FactoryFormComponent implements OnInit{
private model: Factory;
countries: Country[];
factoryStatuses;
productTypes;
risks;
private errorMessage: string;
private submitted = false;
constructor(private factoryService: FactoryService) {
}
ngOnInit(): void {
this.countries = this.factoryService.getCountry()
.subscribe(countries => this.countries = countries,
error => this.errorMessage = error);
}
onSubmit(): void {
this.submitted = true;
}}
factory-form.component.html extrait
<div class="col-lg-3">
<select class="form-control" name="Country">
<option *ngFor="let country of countries" [value]="country.id">{{country.name}}</option>
</select>
</div>
Je reçois une erreur d'exécution comme ci-dessous:
Erreur: TypeScript a trouvé les erreurs suivantes:
C: /Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/factory-form.component.ts (30, 9): Type "Abonnement" ne peut pas être affecté au type "Pays []".
La propriété 'longueur' est manquante dans le type 'Abonnement'.
C: /Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/shared/country.ts (2, 15): ';' attendu. à BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Projects\Ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-TypeScript.js: 120: 19) à BroccoliTypeScriptCompiler.build (C:\Projects\Ethical_resourcing src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-TypeScript.js: 43: 10) sur C:\Projects\ethics_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\broccoli- caching-writer\index.js: 152: 21 at lib $ rsvp $$ internal $$ tryCatch (C:\Projects \hic_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js : 1036: 16) à la lib $ rsvp $$ internal $$ invokeCallback (C:\Projects\ethics_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js: 1048: 17) à lib $ rsvp $$ internal $$ publish (C:\Projects \hic_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js: 1019: 11) à lib $ rsvp $ asap $ $ flush (C:\Projects\Ethics_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modu les\rsvp\dist\rsvp.js: 1198: 9) à nextTickCallbackWith0Args (node.js: 420: 9) à process._tickCallback (node.js: 349: 13)
Maintenant, si je change le type de observable et pays en tout, j'obtiens en dessous de l'erreur
EXCEPTION ORIGINALE: Impossible de trouver un objet de prise en charge différent "[objet objet]" de type "objet". NgFor ne prend en charge que la liaison à des Iterables tels que les tableaux.
Oui, le type doit être un Observable
et vous devez utiliser un canal asynchrone pour rendre ngFor
heureux:
*ngFor="let country of countries | async"
Ou une autre option consiste à conserver Country[]
tapez mais abonnez-vous et affectez countries
au tableau:
this.factoryService.getCountry() // note, removed this.countries =
.subscribe(
countries => this.countries = countries,
error => this.errorMessage = error
);