简体   繁体   English

从api获取数据时,Angular 2+用ngFor填充html表

[英]Angular 2+ filling an html table with ngFor when data is get from api

I'm quite new to Angular so although I'm trying to accomplish something I guess it's not difficult I'm stuck and need your help. 我对Angular还是很陌生,所以尽管我正在尝试完成某些工作,但我认为坚持下去并需要您的帮助并不难。

What I need to do is to fill an html table with clients data on button click and after data is received from an api call. 我需要做的是在单击按钮时以及从api调用接收到数据之后,用客户端数据填充html表。

I'm being able to display "fixed" data with ngFor if I define it as a public property of the TypeScript class as seen with clientsData1 (I leave it as an example), but cannot bind ngFor to variable containing json result (clientsData) changes. 如果我将其定义为TypeScript类的公共属性(如clientsData1所示),则可以使用ngFor显示“固定”数据(但我将其作为示例),但是无法将ngFor绑定到包含json结果(clientsData)的变量变化。

In short, what I'm trying to do is when I click button I launch getItems method and as soon as getItems has a result I need to update the table. 简而言之,我想要做的就是单击按钮时启动getItems方法,并且一旦getItems得到结果,我就需要更新表。

This is my TypeScript class: 这是我的TypeScript类:

import {Component} from '@angular/core';
import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable }     from 'rxjs/Observable';

import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';

@Injectable()
@Component({
  selector: 'demo-app',
  templateUrl: 'app/views/app.component.html'
})
export class AppComponent {
  public clientsData : string;
  private clientsUrl : string = 'http://www.mocky.io/v2/5808862710000087232b75ac';
  public clientsData1 : any = [{'id': 1}, {'id': 3}, {'id': 5}];
  constructor (private http: Http) { }
  ngOnInit() {
    let btnGetClients = document.getElementById("btnGetClients");
    btnGetClients.addEventListener("click", (e:Event) => this.getItems()
        .subscribe(
          ipdata => this.clientsData = ipdata.clientsJson
        ));
  }  
  getItems(): Observable<IPData> {    
        return this.http.get(this.clientsUrl)
                        .map(this.extractData);
  }
  extractData(res: Response) {
    return res.json();
  }
}
class IPData {
  public clientsJson : string;
}

And this is the html template: 这是html模板:

<h1>Insurance App</h1>
<hr />
<button id="btnGetClients">Get Clients</button>
<br/><br/>
<table>
    <thead>
        <th>Id</th>
        <th>Name</th>
        <th>Email</th>
        <th>Role</th>
    </thead>
    <tbody *ngFor="let client of clientsData">
        <tr>
            <td>{{client.id}}</td>
        </tr>
    </tbody>
</table>

Any help will be much appreciated. 任何帮助都感激不尽。

Thanks. 谢谢。

Firstly this is bad practice to use any DOM manipulation in your TS files. 首先,在TS文件中使用任何DOM操作都是一种不好的做法。 You can add click event handler like this 您可以像这样添加点击事件处理程序

<button (click)='getItemsSubscription()'>Get Clients</button>

and to iterate trough array that are not present from the moment when component are created you need to use ngFor like this 并迭代从创建组件开始就不存在的槽式数组,您需要像这样使用ngFor

 <tbody *ngFor="let client of clientsData">
        <tr>
            <td>{{client?.id}}</td>
        </tr>
 </tbody

with a quote mark on client. 在客户端带有引号。 Quote mark means that you will get your data rendered when you will have it on you component lexical environment, or won't render it at all. 引号表示将数据呈现在组件词法环境中或根本不呈现时,您将获得它。

And one more thing if you want to call data with a button click. 还有一件事情,如果您想通过单击按钮来调用数据。 When you calling to a function you are not subscribing to it, so you need to wrap it up and do something like this 当您调用函数时,您无需订阅它,因此您需要将其包装起来并执行类似的操作

  getItemsSubscription() {
       this.getItems().subscribe(
              ipdata => this.clientsData = ipdata.clientsJson
        }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM