angular - 从 API 响应动态创建 md-card

标签 angular typescript angular-material

我正在调用 API 并存储大量用户配置文件,我希望能够为每个配置文件动态创建卡片(Angular Material Design md-card)。返回的配置文件数量可能会有所不同,因此这需要是动态的。

这是我的组件文件,它发出 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: "foobar@foobar.com", image: "/profile/image/foobar/foobar.jpg", phoneNumber: "99999999"},

1: {fullName: "Foo Bar1", emailAddress: "foobar1@foobar.com", image: "/profile/image/foobar1/foobar1.jpg", phoneNumber: "919999999"}

但是,没有呈现任何md-card。我检查过 profiles 不为空。如何根据配置文件的数量动态创建卡片并使用配置文件对象中的值填充内容?

最佳答案

您可以尝试使用 rxjs 中的 BehaviorSubject 并从响应中发出配置文件。在您的模板中使用 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/platform 找到更多信息。单一 repo 。它将让您对应用程序的状态拥有巨大的控制权,并且可以更轻松地管理您的数据和控制来自外部 API 的请求/响应。

关于angular - 从 API 响应动态创建 md-card,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46045819/

相关文章:

javascript - 循环遍历 Observable 数据,推送到数组,并显示数组 typescript 的所有结果

javascript - 模块构建失败 : TypeError: Cannot read property 'exclude' of undefined(awesome-typescript-loader)

angular - 如何对这个 Angular typescript Http Error Interceptor 进行单元测试,该拦截器从管道 observable 中捕获错误?

angular - 使用 forkjoin 合并 http observables

Angular matDatepicker 区域设置无法在输入框中输入内容

html - 垫扩展面板删除边框

angular - ngx-mat-file-input mat-form-field 必须包含一个 MatFormFieldControl

angular - 在 Angular CLI 中使用 ng build --prod 时使用 cdn 而不是本地服务

node.js - 使用 Angular 和 NodeJS 进行 Google 2 因素身份验证

javascript - 从Reducer调用选择器