使用新的 Array() 初始化 *ngFor
Initializing *ngFor with a new Array()
Angularv5
我的搜索组件从返回搜索结果承诺的服务中检索数据。在页面加载时,我的 "searchResults" 数组为空(= new Array()),直到在页面中调用搜索并返回承诺。
*ngFor 抛出错误,因为上面提到的 "searchResults" 在页面加载时为空。在填充搜索结果之前如何避免这种情况?
服务:
getSearchResults(searchTerm: string, resourceType: string, pageSize: number = 9999, pageNumber: number = 1): Promise<object> {
const search = {
Term: searchTerm,
ResourceType: resourceType,
PageSize: pageSize,
PageNum: pageNumber,
ModuleId: moduleId
};
const searchHeader = {headers: this.getHttpHeaders()};
const promise = new Promise((resolve, reject): void => {
this.http.post(this.apiRoot, search, searchHeader).toPromise()
.then(response => {
resolve(JSON.parse(response['_body']));
})
.catch(error => {
reject(error);
});
});
return promise;
}
组件:
submitSearch(): void {
this.siteSearchService.getSearchResults(this.searchString, this.selectedResourceType)
.then(response => {
let dto: DTO.SearchResults = <DTO.SearchResults>response;
this.totalHits = dto.TotalHits;
this.searchResults = dto.Results;
}).catch(error => {
console.log(error);
});
}
模板:
<div class="row" *ngIf="searchResults" style="margin:25px;">
<div class="col-xs-12 result-row" *ngFor="let result in searchResults">
<div class="row">
<div class="col-xs-12 col-sm-10">
<a href [href]="result.Url" target="_blank" class="search-result-link">
<h3>{{result.Title}}</h3>
</a>
<p>{{result.Description}}</p>
</div>
<div class="col-xs-12 col-sm-2">
ToDo: Button
</div>
</div>
</div>
</div>
我的解决方法是使用 async
管道。这会让 Angular 知道在尝试使用 ngFor 循环之前等待结果到达。我会把 searchResults
变成一个在每次搜索结束时发出结果的可观察对象。
在视图中,每次单击按钮时都会发出一个事件:
<input #searchInput />
<button (click)="searchSubject.next(searchInput.value)">Search</button>
组件中class:
// Will emit each new search term when user clicks search button
searchSubject = new Subject<string>();
// Will trigger the search each time the searchSubject emits:
searchResults = searchSubject
.switchMap(term => this.siteSearchService.getSearchResults(term));
.map(response => response.Results)
.catch(err => console.error(err));
最后修改模板使用管道:
<div *ngFor="let result of searchResults | async">
async pipe会订阅searchResults
并开始监听点击事件。一旦您的组件被销毁,Angular 将为您取消订阅。
只需尝试使用 *ngIf="searchResults"
并在您的代码中替换
*ngFor="let result in searchResults"
和 *ngFor="let result of searchResults"
希望能解决您的问题
Angularv5
我的搜索组件从返回搜索结果承诺的服务中检索数据。在页面加载时,我的 "searchResults" 数组为空(= new Array()),直到在页面中调用搜索并返回承诺。
*ngFor 抛出错误,因为上面提到的 "searchResults" 在页面加载时为空。在填充搜索结果之前如何避免这种情况?
服务:
getSearchResults(searchTerm: string, resourceType: string, pageSize: number = 9999, pageNumber: number = 1): Promise<object> {
const search = {
Term: searchTerm,
ResourceType: resourceType,
PageSize: pageSize,
PageNum: pageNumber,
ModuleId: moduleId
};
const searchHeader = {headers: this.getHttpHeaders()};
const promise = new Promise((resolve, reject): void => {
this.http.post(this.apiRoot, search, searchHeader).toPromise()
.then(response => {
resolve(JSON.parse(response['_body']));
})
.catch(error => {
reject(error);
});
});
return promise;
}
组件:
submitSearch(): void {
this.siteSearchService.getSearchResults(this.searchString, this.selectedResourceType)
.then(response => {
let dto: DTO.SearchResults = <DTO.SearchResults>response;
this.totalHits = dto.TotalHits;
this.searchResults = dto.Results;
}).catch(error => {
console.log(error);
});
}
模板:
<div class="row" *ngIf="searchResults" style="margin:25px;">
<div class="col-xs-12 result-row" *ngFor="let result in searchResults">
<div class="row">
<div class="col-xs-12 col-sm-10">
<a href [href]="result.Url" target="_blank" class="search-result-link">
<h3>{{result.Title}}</h3>
</a>
<p>{{result.Description}}</p>
</div>
<div class="col-xs-12 col-sm-2">
ToDo: Button
</div>
</div>
</div>
</div>
我的解决方法是使用 async
管道。这会让 Angular 知道在尝试使用 ngFor 循环之前等待结果到达。我会把 searchResults
变成一个在每次搜索结束时发出结果的可观察对象。
在视图中,每次单击按钮时都会发出一个事件:
<input #searchInput />
<button (click)="searchSubject.next(searchInput.value)">Search</button>
组件中class:
// Will emit each new search term when user clicks search button
searchSubject = new Subject<string>();
// Will trigger the search each time the searchSubject emits:
searchResults = searchSubject
.switchMap(term => this.siteSearchService.getSearchResults(term));
.map(response => response.Results)
.catch(err => console.error(err));
最后修改模板使用管道:
<div *ngFor="let result of searchResults | async">
async pipe会订阅searchResults
并开始监听点击事件。一旦您的组件被销毁,Angular 将为您取消订阅。
只需尝试使用 *ngIf="searchResults"
并在您的代码中替换
*ngFor="let result in searchResults"
和 *ngFor="let result of searchResults"
希望能解决您的问题