我正在Angular 5中构建一个非常粗糙的CRUD应用程序(这是我第一次真正使用该框架)。在大多数情况下,我的所有工作都很好。
该表显示来自本地json服务器的数据,模态显示表单,并且一旦提交便接受数据。但是,除非我手动刷新页面,否则提交表单后不会显示新数据。
我想做的是单击“添加客户”按钮后,模式关闭,表格显示添加的记录。以下是有关区域的主要代码。我觉得我就在那里,但我无法获得最后的联系。
请让我知道是否需要更多详细信息/信息。
home.component.ts
export class HomeComponent implements OnInit {
display='none';
showNew: Boolean = false;
constructor(private http: Http) { }
/*
1. initiate the customers array
2. data is fetched from local json server with data storage
3. results stored in the customers array
4. function called
*/
customers = [];
fetchData = function() {
this.http.get("http://localhost:5555/customers").subscribe(
(res: Response) => {
this.customers = res.json();
}
)
}
/*
1. Create object
2. Create function to read form data
*/
customerObj:object = {};
addNewCustomer = function(customer) {
this.customerObj = {
"firstname": customer.firstname,
"lastname": customer.lastname
}
this.http.post("http://localhost:5555/customers", this.customerObj).subscribe((res:Response) => {
console.log(res);
this.showNew = true;
})
}
onCloseHandled(){
this.display='none';
}
openModal(){
this.display='block';
}
ngOnInit() {
this.fetchData();
}
}
home.component.html
<div class="container">
<h1>CUSTOMERS</h1>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<tr *ngFor = "let customer of customers">
<td>{{customer.id}}</td>
<td>{{customer.firstname}}</td>
<td>{{customer.lastname}}</td>
</tr>
</tbody>
</table>
<br/>
<div class="text-left">
<!-- open a modal window by clicking button-->
<button type="submit" class="btn btn-primary" (click)="openModal()">New</button>
</div>
</div>
<!-- Modal for adding new customer -->
<div class="backdrop" [ngStyle]="{'display':display}"></div>
<div class="modal" tabindex="-1" role="dialog" [ngStyle]="{'display':display}">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add New Customer</h4>
</div>
<div class="modal-body">
<form id = "formNewCustomer" name = "formNewCustomer" #customerData = "ngForm" (ngSubmit) = "addNewCustomer(customerData.value)">
<label>First Name</label><input type ="text" name = "firstname" id = "firstname" placeholder="First Name" ngModel><br>
<label>Last Name</label><input type ="text" name = "lastname" id = "lastname" placeholder="Last Name" ngModel><br>
<input type="submit" value = "Add Customer">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" (click)="onCloseHandled()" >Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal !-->
// Just add this line this.fetchData();
this.http.post("http://localhost:5555/customers",
this.customerObj).subscribe((res:Response) => {
console.log(res);
this.showNew = true;
this.fetchData();
})
首先,在*ngFor
循环中,您需要添加跟踪:
<tr *ngFor = "let customer of customers; trackBy: someTrackingFunction">
(发明someTrackingFunction
,它应明确标识一个客户-对象的ID,例如。]
然后,您可以在帖子中简单地将新客户添加到数组中:
this.http.post("http://localhost:5555/customers", this.customerObj)
.subscribe((res: Response) => {
const newCustomer = // usually, in REST APIs, res will be the new customer object.
this.customers = [...this.customers, newCustomer].sort(someOptionalSortingFunction);
BTW,您是否需要在响应对象上手动调用json()
?已经过了很长时间了。为什么不使用(不是那个新的)HttpClientModule?
添加新客户后,您将需要重新获取数据。
类似:
addNewCustomer(customer) {
const customerObj = {
"firstname": customer.firstname,
"lastname": customer.lastname
};
this.http
.post("http://localhost:5555/customers", customerObj)
.pipe(
switchMap(() => this.fetchData())
).subscribe((res:Response) => {
console.log(res);
// not sure if this.showNew is required? leaving it in for completeness
this.showNew = true;
});
}
请注意,我是如何从switchMap内调用fetchMap的。 switchMap只是意味着在第一个可观察对象返回之后,请切换到新的可观察对象,然后再返回到订阅主体。
NB-您不需要在类函数上使用function()
语法。
编辑:
如果要使用此方法,则需要在此处重构fetchData方法。
ngOnInit() {
this.fetchData().subscribe();
}
// TODO: return array of interfaces, like Customer[]
fetchData(): Observable<[]> {
return this.http
.get("http://localhost:5555/customers")
.pipe(
// use map to transform the raw http response into a known type
map(res => res.json())
// use tap to assign the mapped response to a property
tap(customers => this.customers = customers)
);
}
http调用通常会提供某种服务,返回可观察到的内容(而不是订阅)。然后,您将在组件中订阅它们。
而且通常也应该处理接口,而不是传递大量的json对象。这就是打字稿中的类型;)