我的Angular2 typescript项目实现了一件奇怪的事情。我有来自类型为"Level"的Web服务的对象(它与来自Web服务的Json具有相同的属性)。在运行时,来自Web服务的Level的属性在开头有大写字母(Pascal大小写),而我的typescript项目中的属性有小字母(在浏览器的开发人员调试工具中可见)。
我想我需要以某种方式将json属性映射到某个地方,而不是到处写"as Level[]"来进行强制转换。我该怎么做?
关于我应该发布一些代码的问题的更新:
(控制器)
ngOnInit(): void {
this.levelsObservable = this.levelsService.getAllLevels();
this.levelsObservable.subscribe(
data => console.log(data)
);
}
(服务)
observable : Observable<Response>;
getAllLevels(): Observable<Level[]> {
this.observable = this.achievementsService.getAllAchievements(this.allLevelsUrlPart);
return this.observable
.map((response: Response) => {
const srcData = response.json() as Level[];
return srcData;})
.catch(error => this.handleError(error));}
getAllAchievements(detailPath): Observable<Response> {
// prepare request url and header
this.specificUrl = this.webServiceUrl + detailPath;
this.headers.append('Content-type', 'application/json');
let options = new RequestOptions({ headers: this.headers });
this.result = this.http.get(this.specificUrl, options)
.catch(error => this.handleError(error));
return this.result;}
更新:在下面的一个答案的帮助下,我对代码进行了一些润色(上面没有集成,因为这对解决主要问题不重要)。我试图使用下面的另一个答案来处理camel情况,但它不起作用(我有一个数组,数组中有具有属性的对象,但迭代器方法无法访问对象的属性)。
更新:我终于做到了(!):)我把这篇文章缩短了一点,现在将在下面发布我的解决方案。它肯定不是最漂亮的,但我很高兴在四处寻找了几个小时后有了一个。感谢所有帮助我的人,他们在这里做出了伟大的贡献!
您可以使用它来获取小写对象。
modifiedSrc(srcData){
let obj = {};
Object.keys(srcData).forEach((key)=>{
obj[key.uncapitalize()] = srcData[key];
})
return obj
}
String.prototype.uncapitalize = function() {
return this.charAt(0).toLowerCase() + this.slice(1);
}
然后您可以返回修改后的数据
getAllLevels(): Observable<Level[]> {
this.observable = this.achievementsService.getAllAchievements(this.allLevelsUrlPart);
return this.observable
.map((response: Response) => {
const srcData = response.json() as Level[];
return this.modifiedSrc(srcData);})
.catch(error => this.handleError(error));}
您已经使这两种方法都变得复杂。简化为
this.webServiceUrl = "http...." ; // your service end point address
this.headers.append('Content-type', 'application/json');
let options = new RequestOptions({ headers: this.headers });
// For all your error handling
private handleError(error: Response) {
console.log(error);
return Observable.throw(error.json().error || 'Internal Server error');
}
您的服务方法可以使用类似的TypeCasting
getAllLevels(detailPath): Observable<Level[]> {
return this.http.get(detailPath, options)
.map((response: Response) => <Level[]>response.json())
.catch(this.handleError);
}
您的组件应该以的身份向您的服务提出请求
ngOnInit() : void{
this._myService.getAllLevels()
.subscribe(levels => this.levels = levels,
error =>this.errorMessage =<any> error);
}
您的变量声明必须像一样
levels:Level[];
最后。。。我找到了解决方案!当然不是最漂亮的,但很容易理解,并经过艰苦的工作和研究:
private useLevelProperties (response: any): Level[]{
let levels: Level[] = [];
Object.keys(response).forEach((key) => {
//create a new object and just take out the json parts needed. The webservice retrieves Pascal case letters, so we
//need to convert them into camel case ones.
this.level = new Level(response[key]["AchievementId"], response[key]["Image"],
response[key]["GrantedTo"], response[key]["GrantedBy"], response[key]["GrantedWhen"], response[key]["Description"],
response[key]["Name"], response[key]["CompetitionCode"], response[key]["Number"]);
levels[key] = this.level;
});
return levels;
};
另一种选择是在服务器端为camel case添加一个额外的json选项:例如服务器端camel casing