我正在使用 Angular 4。客户页面上有一个搜索按钮。如果用户单击此按钮,客户列表将显示在表格中。
我正在尝试使用 *ngFor 将客户列表绑定(bind)到表。但是,当单击搜索按钮时,客户列表将附加到表中的当前数据中。
我的期望是表格清晰并且只显示新数据。 请查看我下面的代码并建议如何解决此问题。非常感谢。
客户列表.component.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { Customer } from './customer';
import { CustomerService } from './customer.service';
@Component({
selector: 'customer-list',
templateUrl: './customer-list.component.html',
providers: [CustomerService]
})
export class CustomerListComponent {
public customers: Customer[] = [];
public searchTerm: string;
constructor(private customerService: CustomerService) {
}
onSearchClicked(): void {
this.customerService.searchSimilarCustomers(this.searchTerm);
this.customers = this.customerService.customers;
}
}
客户列表.component.html
<div class="row">
<div class="col-md-6">
<button class="btn btn-primary" data-toggle="modal" data-target="#customer-detail"><i class="fa fa-plus"></i> Create customer</button>
</div>
<div class="col-md-6">
<form class="form-inline pull-right">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" name="searchTerm" [(ngModel)]="searchTerm" placeholder="Search customer">
</div>
</div>
<button type="submit" class="btn btn-primary" (click)="onSearchClicked()"><i class="fa fa-search"></i> Search</button>
</form>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Reference</th>
<th>Last Name</th>
<th>Middle Name</th>
<th>First Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let customer of customers">
<td>{{ customer.id }}</td>
<td>{{ customer.reference }}</td>
<td>{{ customer.lastName }}</td>
<td>{{ customer.middleName }}</td>
<td>{{ customer.firstName }}</td>
</tr>
</tbody>
</table>
客户.service.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Customer } from './customer';
@Injectable()
export class CustomerService {
private customersUrl = "http://localhost:60001/api/v1/customers";
public customers: Customer[] = [];
constructor(private http: Http) { }
searchSimilarCustomers(searchTerm: string, page: number = 1, itemsPerPage: number = 10) {
var me = this;
if (!searchTerm) {
searchTerm = "";
}
var url = me.customersUrl + `?searchTerm=${searchTerm}&page=${page}&itemsPerPage=${itemsPerPage}`;
me.http.get(url).subscribe(result => {
for (var item of result.json().data) {
var customer = me.MapCustomerFromResource(item.data);
me.customers.push(customer);
}
}, error => console.error(error));
}
private MapCustomerFromResource(data: any): Customer {
return {
id: data.id,
reference: data.attributes.reference,
firstName: data.attributes.firstName,
middleName: data.attributes.middleName,
lastName: data.attributes.lastName,
gender: data.attributes.gender
};
}
}
最诚挚的问候,
凯文
最佳答案
me.customers.push
<= 服务正在添加到同一个数组中,并且该数组被重用。如果您想跟踪所有客户和您刚刚返回的客户,您必须通过创建 2 秒数组来区分。
此外,我不喜欢您的调用结构,没有明确的关注点分离,这导致您引入难以追踪的逻辑错误。坚持内置的订阅机制,以便您的服务返回数据但无状态(即不跟踪客户)。
查看更改后的代码,这允许组件订阅
从服务返回的可观察对象并从服务中删除状态。这是一种更干净的方法。如果您想跟踪所有客户,请在您的组件(而不是服务)中添加另一个数组,在返回时推送更多客户。
customer-list.component.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import { Customer } from './customer';
import { CustomerService } from './customer.service';
@Component({
selector: 'customer-list',
templateUrl: './customer-list.component.html',
providers: [CustomerService]
})
export class CustomerListComponent {
public customers: Customer[] = [];
public searchTerm: string;
constructor(private customerService: CustomerService) {
}
onSearchClicked(): void {
this.customerService.searchSimilarCustomers(this.searchTerm)
<em><strong>.subscribe(customers => {
this.customers = customers;
});</strong></em>
}
}
customer.service.ts
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Customer } from './customer';
@Injectable()
export class CustomerService {
private customersUrl = "http://localhost:60001/api/v1/customers";
<em><strong>// No more customers state</strong></em>
constructor(private http: Http) { }
searchSimilarCustomers(searchTerm: string, page: number = 1, itemsPerPage: number = 10) : Observable<Customer[]> {
if (!searchTerm) {
searchTerm = "";
}
var url = this.customersUrl + `?searchTerm=${searchTerm}&page=${page}&itemsPerPage=${itemsPerPage}`;
return this.http.get(url).<em><strong>map(result => {
var customers: Customer[] = []
for (var item of result.json().data) {
var customer = this.MapCustomerFromResource(item.data);
customers.push(customer);
}
return customers;
}</strong></em>, error => console.error(error));
}
private MapCustomerFromResource(data: any): Customer {
return {
id: data.id,
reference: data.attributes.reference,
firstName: data.attributes.firstName,
middleName: data.attributes.middleName,
lastName: data.attributes.lastName,
gender: data.attributes.gender
};
}
}
关于angular - 如何防止 Angular ngFor 将数据追加到当前列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47039325/