我正在使用Angular 4.客户页面上有一个搜索按钮。如果用户单击此按钮,则会在表格中显示客户列表。
我尝试使用* ngFor将客户列表绑定到表中。但是,当单击搜索按钮时,客户列表将附加到表中的当前数据。
我的期望是表格清晰,只显示新数据。 请查看下面的代码并建议如何解决此问题。非常感谢你。
客户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);
this.customers = this.customerService.customers;
}
}

客户list.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>
&#13;
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";
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
};
}
}
&#13;
致以最诚挚的问候,
凯文
答案 0 :(得分:3)
me.customers.push
&lt; =服务正在添加到同一个数组,并且该数组被重用。如果您想跟踪刚刚返回的所有客户和客户,则必须通过创建2秒数组来区分。
此外,我不喜欢你的通话结构,没有明确的关注点分离导致你引入难以追踪的逻辑错误。坚持内置的订阅机制,因此您的服务返回数据但是无状态(即不跟踪客户)。
查看更改的代码,这允许组件subscribe
到服务返回的observable并从服务中删除状态。这是一种更清洁的方法。如果要跟踪所有客户,请在组件中添加另一个阵列(而不是服务),以便在返回时推送更多客户。
<强>客户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)
.subscribe(customers => {
this.customers = customers;
});
}
}
<强> 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";
// No more customers state
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).map(result => {
var customers: Customer[] = []
for (var item of result.json().data) {
var customer = this.MapCustomerFromResource(item.data);
customers.push(customer);
}
return customers;
}, 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
};
}
}
答案 1 :(得分:0)
您不应该将push()方法用于您要实现的目标。这会将数据添加到现有列表中。
me.http.get(url).subscribe(result => {
for (var item of result.json().data) {
var customer = me.MapCustomerFromResource(item.data);
me.customers.push(customer);
}
}
如果您希望更新客户列表,您应该执行以下操作:
me.http.get(url).subscribe(
(res) => me.onSuccess(res.json),
(res) => me.onError(res.json)
);
private onSuccess(data) {
me.customers = data;
}
private onError(error) {
this.errorMessage = error.toString();
}
答案 2 :(得分:0)
在开始推送结果之前,您应该清除服务中的customers
。
答案 3 :(得分:0)
只需在订阅中设置me.customers = []
。
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 => {
me.customers = []; // This line will fix that issue.
for (var item of result.json().data) {
var customer = me.MapCustomerFromResource(item.data);
me.customers.push(customer);
}
}, error => console.error(error));
}