如何解决如何从不同的来源设置我的接口对象的值
我有一个包含以下项目的 json 文件:
[
{"id": 1,"fileName": "1.txt","title": "First Kidney Transplant in the Region"},{"id": 2,"fileName": "2.txt","title": "Another article"}
]
我有一个带有以下对象的接口 INewsArticle[]
export interface INewsArticles{
id : number,fileName : string,title : string,content : Text
}
除了内容之外的所有内容都是从我的 json 文件中加载的。我想要做的是使用一个订阅从.txt文件中获取每篇文章的相应内容,我不知道如何在打字稿中做到这一点。
这是我的订阅代码:this.svcNewsArticles.LoadArticles().subscribe(data => this._newsArticles = data);
这是我的服务:
private _srcArticles : string = "./assets/news-articles/newsList.json";
constructor(private http:HttpClient) { }
LoadArticles() : Observable<INewsArticles[]>{
return this.http.get<INewsArticles[]>(this._srcArticles);
}
我目前拥有的是获取我的 INewsArticles[],使用 *ngFor 将其绑定到 HTML,然后调用另一个方法来订阅另一个请求,以使用 INewsArticles[] 的参数从我的内容目录加载内容。文件名。但这会导致在控制台上测试时无限循环。
这是我的 HTML:
<div id="divContainer" class="container" fxLayout="row wrap" fxLayout.lt-md="column" fxLayoutAlign="center" fxLayoutGap="20px" [style.marginTop.%]="_marginTop">
<div id="divHeader" [fxHide]="_hideHeader">
<h1>What's New?</h1>
</div>
<mat-card fxFlex.gt-sm="30%" fxFlex.lt-md="95%" *ngFor = "let article of _newsArticles">
<mat-card-header>
<mat-card-title>
{{ article.title }}
</mat-card-title>
</mat-card-header>
<mat-card-content class="scrollable">
{{ getContent(article.fileName) }}
<!-- <embed src='../../../../assets/news-articles/content/{{ article.fileName }}'> -->
<!-- {{ getContent() }} -->
</mat-card-content>
</mat-card>
</div>
这是我的订阅:
getContent(fileName : string){
this.svcNewsArticles.GetContent(fileName).subscribe(data => {console.log(data)},err => {console.log(err)});
}
这是我的服务:
GetContent(fileName : String){
return this.http.get('./assets/news-articles/content/'+fileName,{responseType : 'text'});
}
我是新手,请多多关照。
解决方法
您可以使用任何更高阶的映射运算符(例如 switchMap 或 mergeMap)一起执行这两个 HTML 请求。
像这样:
posts$ = this.http.get<Post[]>(this.postUrl).pipe(
mergeMap(posts =>
forkJoin(
posts.map(post =>
this.http.get<User>(`${this.userUrl}/${post.userId}`).pipe(
map(user => ({
title: post.title,userName: user.name
}))
)
)
)
)
);
您可以在此处找到有效的 Stackblitz:https://stackblitz.com/edit/angular-simple-posts-user-mergemap-deborahk
将其应用于您的代码,它看起来像这样:
this.http.get<INewsArticles[]>(this._srcArticles).pipe(
mergeMap(articles=>
forkJoin(
articles.map(article=>
this.http.get('./assets/news-articles/content/'+article.fileName,{responseType : 'text'}).pipe(
map(content=> ({
id : article.id,fileName : article.fileName,title : article.title,content : content
}))
)
)
)
)
);
注意:这尚未经过语法检查或验证。请提供一个小的 StackBlitz 示例以获得更具体和语法检查的答案。
此代码首先获取所有文章。然后它使用 mergeMap 处理文章并自动订阅内部 Observables。 forkJoin 允许我们使用articles.map 处理文章数组中的每篇文章。
然后我们发出文章内容的 http 请求,并将检索到的数据映射到所需的接口中。
结果是一个包含内容的 Observable
更新:您可以使用对象解构来稍微缩短语法:
this.http.get<INewsArticles[]>(this._srcArticles).pipe(
mergeMap(articles=>
forkJoin(
articles.map(article=>
this.http.get('./assets/news-articles/content/'+article.fileName,{responseType : 'text'}).pipe(
map(content=> ({
...article,content : content
}))
)
)
)
)
);
...article
语法复制所有文章属性。然后您只需要添加 content
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。