Инициализация *ngFor с новым массивом()

угловой v5

Мой компонент поиска извлекает данные из службы, возвращающей обещание результата поиска. При загрузке страницы мой массив «searchResults» пуст (= новый массив ()) до тех пор, пока поиск не будет вызван на странице и обещание не будет возвращено.

* 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> 

person Cody Tolene    schedule 16.11.2017    source источник
comment
ты пробовал : <div class="row" *ngIf="totalHits > 0 && searchResults " style="margin:25px;"> ?   -  person Mohamed Ali RACHID    schedule 16.11.2017
comment
Я сделал, к сожалению, это не работает. Все еще показывает ошибку компиляции: [ERROR -›]*ngFor=let result in searchResults   -  person Cody Tolene    schedule 16.11.2017
comment
Вы можете удалить ? после searchResults в ngFor ?   -  person Mohamed Ali RACHID    schedule 16.11.2017
comment
Обновлен исходный пост, чтобы включить ваши рекомендации, но все еще получая ту же ошибку времени компиляции, упомянутую в моем комментарии выше.   -  person Cody Tolene    schedule 16.11.2017
comment
Попробуйте просто *ngIf="searchResults" и, как говорит Мохаммед, попробуйте удалить ? в конце результатов поиска   -  person Srinivas Valekar    schedule 16.11.2017
comment
Шринивас, применил к исходному сообщению. Ошибка компиляции остается неизменной. [ОШИБКА -›]*ngFor=позволить результат в searchResults›   -  person Cody Tolene    schedule 16.11.2017
comment
я думаю, что это должно быть *ngFor= "let result of searchResults", а не *ngFor="let result in searchResults"   -  person Srinivas Valekar    schedule 16.11.2017
comment
Шринивас, СПАСИБО!   -  person Cody Tolene    schedule 16.11.2017


Ответы (2)


Просто попробуйте с *ngIf="searchResults", а также в своем коде замените *ngFor="let result in searchResults" на *ngFor="let result of searchResults"

Надеюсь, это решит вашу проблему

person Srinivas Valekar    schedule 16.11.2017

Мое исправление состояло бы в том, чтобы использовать канал async. Это позволит Angular дождаться получения результатов, прежде чем пытаться выполнить цикл с ngFor. Я бы превратил searchResults в наблюдаемую, которая выдает результаты в конце каждого поиска.

В представлении генерируйте событие каждый раз, когда нажимается кнопка:

<input #searchInput />
<button (click)="searchSubject.next(searchInput.value)">Search</button>

В классе компонентов:

// 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">

асинхронный канал подпишется на searchResults и начнет прослушивать событие click. Как только ваш компонент будет уничтожен, Angular отпишется от вас.

person BeetleJuice    schedule 16.11.2017
comment
классные предложения! Большое спасибо! - person Cody Tolene; 16.11.2017