我有一个角度服务,它从http get获取值,然后在返回时将值映射到特定对象类型的Observable。有时,属性之一的值是一个字符串,有时它是一个空值,我想将其设置为默认的空字符串。
是否有比我现有的方法更优雅的方法?
我尝试为我感兴趣的特定字段传递一个布尔值template.AreaId属性,但是我担心,随着时间的推移,更多的属性可能会出现此问题,因为创建了更多的模板对象。 / p>
getTaskFromTemplate(extraChildTask:string, hasArea: boolean) : Observable<Task>{
if (hasArea){
return this.templateService.getTemplateByName(extraChildTask).pipe(
map(template => {
return {
WorkItemId:'',
WorkItemType:'Task',
Title: template.Title,
Description: template.Description,
AssignedTo: '',
TeamProject: template.TeamProjectName,
AreaPathId: template.AreaId.toString(),
IterationPathId: '',
Application:'',
State:'',
TargetDate: null,
OriginalEstimate: 0,
CompletedWork: 0,
RemainingWork:0,
BusinessPriority: '',
CreatedBy:'',
CreatedDate: null,
Priority:'',
Notes:'',
AreaPathName:'',
IterationPathName:'',
};
}),
catchError((error: HttpErrorResponse) => { return throwError(error); })
)
}
return this.templateService.getTemplateByName(extraChildTask).pipe(
map(template => {
return {
WorkItemId:'',
WorkItemType:'Task',
Title: template.Title,
Description: template.Description,
AssignedTo: '',
TeamProject: template.TeamProjectName,
AreaPathId: '',
IterationPathId: '',
Application:'',
State:'',
TargetDate: null,
OriginalEstimate: 0,
CompletedWork: 0,
RemainingWork:0,
BusinessPriority: '',
CreatedBy:'',
CreatedDate: null,
Priority:'',
Notes:'',
AreaPathName:'',
IterationPathName:'',
};
}),
catchError((error: HttpErrorResponse) => { return throwError(error); })
)
}
}
这行得通,但我希望有一种方法可以更好地处理字段为null或没有字符串值的情况。
这是我在遇到模板问题之前遇到的东西。AreaId值为null。
getTaskFromTemplate(extraChildTask:string) : Observable<Task>{
return this.templateService.getTemplateByName(extraChildTask).pipe(
map(template => {
return {
WorkItemId:'',
WorkItemType:'Task',
Title: template.Title,
Description: template.Description,
AssignedTo: '',
TeamProject: template.TeamProjectName,
AreaPathId: template.AreaId.toString(),
IterationPathId: '',
Application:'',
State:'',
TargetDate: null,
OriginalEstimate: 0,
CompletedWork: 0,
RemainingWork:0,
BusinessPriority: '',
CreatedBy:'',
CreatedDate: null,
Priority:'',
Notes:'',
AreaPathName:'',
IterationPathName:'',
};
}),
catchError((error: HttpErrorResponse) => { return throwError(error); })
)
}
答案 0 :(得分:1)
从我的评论中扩展出来,关于使用三元运算符的建议如下:
getTaskFromTemplate(extraChildTask:string) : Observable<Task>{
return this.templateService.getTemplateByName(extraChildTask).pipe(
map(template => {
return {
WorkItemId:'',
WorkItemType:'Task',
Title: template.Title,
Description: template.Description,
AssignedTo: '',
TeamProject: template.TeamProjectName,
// Just use a ternary to prevent the `toString()` call if the property
// does not exist on the template
AreaPathId: template.AreaId != null ? template.AreaId.toString() : '',
IterationPathId: '',
Application:'',
State:'',
TargetDate: null,
OriginalEstimate: 0,
CompletedWork: 0,
RemainingWork:0,
BusinessPriority: '',
CreatedBy:'',
CreatedDate: null,
Priority:'',
Notes:'',
AreaPathName:'',
IterationPathName:'',
};
}),
catchError((error: HttpErrorResponse) => { return throwError(error); })
)
}
还扩展了我所说的动态映射属性的潜力(即避免明确指定所涉及的每个属性的映射),一种可能的解决方案的示例可能如下所示:
const { of } = rxjs;
const { map } = rxjs.operators;
const baseTask = {
Title: '',
Description: '',
TeamProjectName: '',
AreaPathId: '',
WorkItemId: '',
WorkItemType: 'Task',
// ...
};
function getTaskFromTemplate(extraChildTask, hasArea) {
return getTemplateByName(extraChildTask).pipe(
map(template => {
// Merges properties the acquired template with those in the base task
// with the properties in the template taking precedence
return Object.assign({}, baseTask, template);
}),
);
}
// Stub implementation that just returns a fixed template
function getTemplateByName(extraChildTask) {
return of({
Title: 'Title',
Description: 'Description',
TeamProjectName: 'Team Project Name',
AreaPathId: 'Area Path ID',
// ...
});
}
// Example usage in action
getTaskFromTemplate('something').subscribe(task => {
console.log(task);
});
<script src="https://unpkg.com/rxjs@6.5.2/bundles/rxjs.umd.min.js"></script>
正如我指出的,如果某些任务属性名称与您需要映射的模板名称不匹配,则可以通过设置一些其他映射步骤来解决。