правильно, я изначально так и думал! спасибо за указание на это :)

аю вызов API и сохраняю несколько пользовательских профилей, и я хочу иметь возможность динамически создавать карты (md-карта Angular Material Design) для каждого профиля. Количество возвращаемых профилей может варьироваться, поэтому оно должно быть динамическим.

Это мой компонентный файл, который делает запрос JSONP и сохраняет профили вprofiles переменная:

import {Component, Injectable, OnInit} from '@angular/core';
import {Jsonp} from '@angular/http';

@Component({
  selector: 'app-staff',
  templateUrl: './staff.component.html',
  styleUrls: ['./staff.component.css']
})
@Injectable()
export class StaffComponent implements OnInit {
  public searchField: string;
  apiRoot = 'this/is/my/api/url';
  public results: JSON;
  public profiles;

  constructor(private jsonp: Jsonp) {
  }

  ngOnInit() {
  }

  setSearchField(field: string){ // ignore this method
    this.searchField = field;
    console.log('Received field: ' + this.searchField);
  }

  search(term: string) {
    const apiUrl = `${this.apiRoot}?search=${term}&rows=10&callback=JSONP_CALLBACK`;
    return this.jsonp.request(apiUrl).map(results => { this.results = results.json(); console.log(this.results['profiles'][0]); this.profiles = results['profiles']; return results.json(); });
  }

}

Это шаблон для вышеуказанного компонента, где я пытаюсь использовать*ngFor создать списокmd-card:

<div class="container-fluid">
  <div class="row justify-content-center">
    <div class="col-md-auto">
      <ul>
        <li *ngFor="let profile of profiles">
          <md-card class="example-card">
            <md-card-header>
              <div md-card-avatar class="example-header-image"></div>
              <md-card-title>{{profile.fullName}}</md-card-title>
              <md-card-subtitle>Department</md-card-subtitle>
            </md-card-header>
            <img md-card-image src="../assets/image.png">
            <md-card-content>
              <p>
                This section of the card will contain information about the result being searched for. It could also be
                accompanied by additional information such as links.
              </p>
            </md-card-content>
            <md-card-actions>
              <button md-button>APPLY</button>
              <button md-button>GO TO xyz</button>
            </md-card-actions>
          </md-card>
        </li>
      </ul>
    </div>
  </div>
</div>

Данные моих профилей представлены в виде массива (предположим, что длина массива не превышает 10) и имеют следующую форму:

0: {fullName: "Foo Bar", emailAddress: "[email protected]", image: "/profile/image/foobar/foobar.jpg", phoneNumber: "99999999"},

1: {fullName: "Foo Bar1", emailAddress: "[email protected]", image: "/profile/image/foobar1/foobar1.jpg", phoneNumber: "919999999"}

Тем не менее, нетmd-cardсдается. Я проверил этоprofiles не пусто Как динамически создавать карточки в зависимости от количества профилей и заполнять содержимое значениями из объектов профиля?

 Aniruddha Das07 сент. 2017 г., 23:34
Копонент не может быть @Injectable (). вы передали классу @component и @Injectable (). Вы можете убедиться, что это не проблема
 cyr-x07 сент. 2017 г., 23:25
this.profiles = results['profiles'] должно бытьthis.profiles = this.results['profiles'] или жеthis.profiles = results.json()['profiles']
 bawse07 сент. 2017 г., 23:29
@cyrix спасибо за это, я исправил это в коде сейчас. Тем не менее, по-прежнему ничего не отображается. Я распечатал массив профилей в консоли, чтобы убедиться, что он не неопределен.
 Faisal07 сент. 2017 г., 14:23
как твояprofiles данные выглядят как? такси, вы добавили это к вашему вопросу?
 bawse07 сент. 2017 г., 23:18
@Faisal Я добавил больше информации оprofiles данные в моем вопросе.

Ответы на вопрос(2)

Observable|promise Так что вам нужно справиться сasync поведение значения, поступающего с сервера.

Угловой обеспечиваютasync Канал, который вы можете использовать в своем шаблоне, чтобы сказать, что когда бы ни приходили данные, отражайте их в моем пользовательском интерфейсе.

Вы можете переместить вызов вашего сервера на@Injectable() сервис, который будет возвращать Observable и хранить его в переменной вашего компонента, а затем в вашем пользовательском интерфейсе вы можете просто использоватьasync труба

<ul>
    <li *ngFor="let profile of profiles | async">
      <md-card class="example-card">
        <md-card-header>

Это прекрасно работает с Observable и http звонками в угловых API. когда ваши угловые нагрузки завершают привязку шаблона, но после этого поступают данные с сервера, поэтому ваши данные не отображаются в пользовательском интерфейсе. так что вы должны справиться с этим асинхронным поведением. надеюсь это поможет :)

 cyr-x07 сент. 2017 г., 23:50
К сожалению, он выполняет вызов API внутри своего компонента и применяет результат внутриmap что, вероятно, приводит к тому, что обнаружение изменения угла не воспринимает изменения. Но ваш ответ будет правильным, еслиprofiles было бы Наблюдаемым, как в моем подходе.
 Aniruddha Das07 сент. 2017 г., 23:48
ооо он использует профиль! я думал, что он использует результат. Я изменю свой ответ, чтобы указать на результат, чтобы он работал
 Aniruddha Das07 сент. 2017 г., 23:51
правильно, я изначально так и думал! спасибо за указание на это :)
 cyr-x07 сент. 2017 г., 23:42
Это не будет работать, потому что он устанавливаетprofiles внутриmap вызов. Следовательноprofiles не наблюдаемый.
Решение Вопроса

Вы можете попробовать использоватьBehaviorSubject изrxjs и выбросить профили из ответа. В вашем шаблоне используйтеasync труба. Это позволит убедиться в том, что обнаружение изменений в Angular подхватит изменения.

private readonly profiles$ = new BehaviorSubject([]);
public readonly profiles$ = this.profiles$.asObservable();

//  ...

search(term: string) {
  const apiUrl = `${this.apiRoot}?search=${term}&rows=10&callback=JSONP_CALLBACK`;
  return this.jsonp.request(apiUrl).map(res => {
    let results = res.json();
    this.profiles$.next(results.profiles);
    return results;
  });
}

и в вашем шаблоне:

<li *ngFor="let profile of profiles$ | async">
  <!--  ... -->
</li>

Кстати: удалить@Injectable декоратор из компонента, компоненты не должны бытьinjectable.

Примечание: вам действительно стоит подумать о переносе вызова API в общую службу, это сохранит логику вашего компонента в чистоте, и вы сможете использовать его и в других компонентах. Также вы можете узнать оredux «шаблон», для этого вы можете посмотреть в@ngrx/store а также@ngrx/effects, Более подробную информацию можно найти на@ Ngrx / платформа monorepo. Это даст вам огромный контроль над состоянием вашего приложения, и вам будет легче управлять вашими данными и контролировать запросы / ответы от внешних API.

 bawse08 сент. 2017 г., 00:15
О да я случайно набралlet profile or profiles$, Я исправил это сейчас. Тем не менее, до сих пор ничего не делается с точки зренияmd-card
 cyr-x07 сент. 2017 г., 23:55
Я думаю ты имеешь ввиду'ngForOf' since it isn't a known property of 'li'Вы импортировалиCommonModule из@angular/common в вашем модуле, содержащем компонент?
 bawse07 сент. 2017 г., 23:52
Спасибо за ваш ответ, я попробовал ваш подход, но я получаю сообщение об ошибке в консоли.Can't bind to 'ngForOr' since it isn't a known property of 'li'. Посоветуйте, пожалуйста, как действовать отсюда. Я также удалил Injectable decorator из компонента, это было ошибкой.
 cyr-x08 сент. 2017 г., 00:06
Угловой не имеетngForOr директива простоngForOf директива, но не могли бы вы добавить свой код модуля, который объявляет компонент к вашему вопросу, пожалуйста?ngForOr ошибка может произойти, если вы набрали*ngFor="let profile or profiles$ | async" вместо*ngFor="let profiles of profiles$ | asyncпотому что угловые "десугары" это вlet-profile [ngForOf]="profiles | async".
 bawse08 сент. 2017 г., 00:00
Нет, ошибка консоли ясно говорит'ngForOr', Я импортировалCommonModule, Вы можете предоставить плункер? Первоначально я следовал этому руководству при настройке своего углового сервиса, поэтому не стесняйтесь использовать API, используемый здесь:codecraft.tv/courses/angular/http/jsonp-with-observables

Ваш ответ на вопрос