如何从不同的来源设置我的接口对象的值
How to set value of my interface object from a different source
我有一个包含以下项目的 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[].fileName。但这在控制台上测试时会导致无限循环。
这是我的 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
.
我有一个包含以下项目的 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[].fileName。但这在控制台上测试时会导致无限循环。
这是我的 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
.