在 ngOnInit() 中使用数据绑定从本地 JSON 文件读取数据会导致未定义的变量
Posted
技术标签:
【中文标题】在 ngOnInit() 中使用数据绑定从本地 JSON 文件读取数据会导致未定义的变量【英文标题】:Read data from a local JSON file with data binding in ngOnInit() results in undefined variable 【发布时间】:2018-05-19 10:59:12 【问题描述】:我正在尝试从 assets
文件夹中的 json 文件中获取数据,然后将此数据分配给一个变量,该变量将绑定到子组件的另一个 @Input
变量。
基于网上的多种解决方案,我这样检索我的JSON数据:
@Injectable()
export class JSONService
constructor(private http: HttpClient)
public fromJSON(jsonFileName: string): Observable<any[]>
let result: any[] = new Array();
let pathToJson: string = "assets/" + jsonFileName + ".json";
return this.http.get(pathToJson).map(data =>
let result: any[] = new Array();
// Apply some treatment on data and push it to the result array
return result;
);
然后我在父组件的ngOnInit()
方法中调用我的服务:
ngOnInit()
this.jsonService.fromJSON("users.json").subscribe(fields =>
this.fields= fields;
console.log(this.fields); // Log (I): this.fields is well defined
);
console.log(this.fields); // Log (II): this.fields is undefined
变量fields
绑定到子组件的地方:
<child-component [childFields] = "fields"></child-component>
问题
我面临的问题是对fromJSON
方法的异步调用导致this.fields
在页面执行生命周期的某个时刻未定义(上面代码中的Log (II)
),这导致将this.fields
变量的未定义值发送到子组件。
如何避免 fields
变量的值未定义,并确保子组件始终加载 json 文件中的数据?
【问题讨论】:
在你的路由中使用解析器,它会调用服务并在组件构造函数中接收响应 【参考方案1】:只需添加 *ngIf 以检查数据是否加载
<child-component *ngIf="fields" [childFields] = "fields"></child-component>
【讨论】:
【参考方案2】:假设你的组件有点像下面
export class SomeComponent implements OnInit
public fields: any[];
ngOnInit()
this.jsonService.fromJSON("users.json").subscribe(fields =>
this.fields = fields;
console.log(this.fields); // Log (I): this.fields is well defined
);
console.log(this.fields); // Log (II): this.fields is undefined
然后您可以使用空数组初始化 fields
public fields: any[] = [];
模板中的或
<child-component *ngIf="fields" [childFields]="fields"></child-component>
【讨论】:
【参考方案3】:服务.ts
@Injectable()
export class JSONService
constructor(private http: HttpClient)
public fromJSON(jsonFileName): Observable<any[]>
console.warn('Retriving Default Data from File.......');
return this.http.get(filename)
.map(this.extractData)
.catch(this.handleError);
private extractData(res: Response)
let body = res.json();
return body || [];
private handleError(error: any)
const errMsg = (error.message) ? error.message :
error.status ? `$error.status - $error.statusText` : 'Server error';
console.error(errMsg);
console.log('Server Error!');
return Observable.throw(errMsg);
parent.component.ts
constructor(public jsonService: jsonService)
ngOnInit()
this.jsonService.fromJSON('assets/users.json').subscribe(
function (success)
this.data = success;
this.datahandle(success);
,
error => console.log('Getting Server Data Error :: ' +
JSON.stringify(error)));
datahandle(jsonData)
console.log('check data' + JSON.stringify(jsonData)); <-----check data
// may parse your jsonData if required
this.fields = jsonData ;
let keys = Object.keys(jsonData);
console.log(keys);
parent.component.html
<child-component *ngIf="fields" [childFields] = "fields"></child-component>
【讨论】:
以上是关于在 ngOnInit() 中使用数据绑定从本地 JSON 文件读取数据会导致未定义的变量的主要内容,如果未能解决你的问题,请参考以下文章
Angular2,TypeScript,如何读取/绑定属性值到组件类(在 ngOnInit 中未定义)[重复]