[英]Angular 15: call a function every time a value changes
我们的教授要求我们使用以下组件构建一个简单的电子商务应用程序:客户、订单、菜单(导航栏)和购物车。 我们需要根据从导航栏的下拉菜单中选择的所选客户在前端显示订单,如图所示:
一旦我们 select 一个客户,它的 Id 就被分配给一个变量,然后它被用来根据客户 id 加载订单(多亏了一个名为 getOrdersByCustomerId 的端点),然后它为每个订单构建一张卡片。 到目前为止,一切都很好。 问题是 function 在初始值为 0 的订单组件中只被调用一次,我们不知道如何在每次 id 更改时进行动态调用。 这是代码:
import { Injectable } from '@angular/core';
import { OrdersService } from './orders.service';
@Injectable({
providedIn: 'root'
})
export class MenuService {
constructor() { }
customerId: number = 0;
onCustomerChange(event: Event) {
this.customerId = Number((<HTMLInputElement> event.target).value);
console.log(this.customerId);
}
}
import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { CustomerService } from 'src/services/customer.service';
import { MenuService } from 'src/services/menu.service';
@Component({
selector: 'app-menu',
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.css']
})
export class MenuComponent implements OnInit {
constructor(public customerService: CustomerService, public menuService: MenuService) {
this.customers = this.customerService.getCustomers();
console.log(this.customers);
}
ngOnInit(): void {
}
title: string = 'E-commerce';
customers: {
id: number,
name: string,
surname: string
}[] = [];
customer!: {
id: number,
name: string,
surname: string
};
links = [
{name: 'Products', href: '/products', disabled: false},
{name: 'Orders', href: '/orders', disabled: false},
{name: 'Cart', href: '/cart', disabled: true},
];
onCustomerChange(event: Event) {
this.menuService.onCustomerChange(event);
}
}
<nav class="navbar navbar-expand-lg bg-primary">
<div class="container-fluid">
<a class="navbar-brand" routerLink="">{{ title }}</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item" *ngFor="let link of links">
<a class="nav-link" aria-current="page" routerLink="{{ link.href }}" routerLinkActive="active">{{ link.name }}</a>
</li>
</ul>
</div>
<div class="d-flex">
<select (change)="onCustomerChange($event)" class="form-select" aria-label="Customer select">
<option value="0">Select customer</option>
<option *ngFor="let customer of customers" value="{{ customer.id }}" >{{ customer.name }} {{ customer.surname }}</option>
</select>
</div>
</div>
</nav>
<!-- [ngModel]="customer.id"
{{ customer.id }}" (change)="-->
import { HttpClient } from '@angular/common/http';
import { Injectable, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { CartService } from './cart.service';
import { CustomerService } from './customer.service';
import { MenuService } from './menu.service';
@Injectable({
providedIn: 'root'
})
export class OrdersService implements OnInit {
constructor(
public httpClient: HttpClient,
public cartService: CartService,
public customerService: CustomerService,
public menuService: MenuService) {
this.loadOrdersByClientId(this.menuService.customerId);
}
ngOnInit(): void {
this.loadOrdersByClientId(this.menuService.customerId);
}
private orders: {
id: number,
products: any,
amount: number,
customer: any
}[] = [];
loadOrdersByClientId(id: number) {
this.httpClient.get(`http://localhost:8080/order/by-client-id/${id}`).subscribe((response) => {
//console.log(id);
Object.entries(response).forEach(([key, value]) => {
this.orders.push(value);
})
})
}
getOrders() {
return this.orders;
}
}
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { OrdersService } from 'src/services/orders.service';
@Component({
selector: 'app-orders',
templateUrl: './orders.component.html',
styleUrls: ['./orders.component.css']
})
export class OrdersComponent implements OnInit {
constructor(public ordersService: OrdersService) {}
ngOnInit(): void {
this.orders = this.ordersService.getOrders();
}
orders: {
id: number,
products: any,
amount: number,
customer: any
}[] = [];
}
<div class="card" style="width: 18rem;" *ngFor="let order of orders">
<div class="card-body">
<h5 class="card-title">{{order.id}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{order.amount}}</h6>
</div>
</div>
自从我们使用 Angular 仅 1 周以来,这些脚本中可能存在大量不良做法,对此深表歉意。 为了简洁起见,我省略了客户端组件,因为它与问题无关(它可以工作,并且可以正确检索 ID)。 先谢谢您的帮助!
似乎当客户发生变化时,只有 customerId 会更新,没有其他内容。 触发新后端调用的一种方法是在 customerId 更新时发出事件。 然后你可以在订单组件中监听它并触发一个新的后端调用。
在您的菜单服务中:
import { Injectable, EventEmitter } from '@angular/core';
import { OrdersService } from './orders.service';
@Injectable({
providedIn: 'root'
})
export class MenuService {
public customerIdUpdate = new EventEmitter();
constructor() { }
customerId: number = 0;
onCustomerChange(event: Event) {
this.customerId = Number((<HTMLInputElement> event.target).value);
this.customerIdUpdate.emit();
console.log(this.customerId);
}
}
然后您可以在您的订单组件中订阅该事件,如下所示:
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { OrdersService } from 'src/services/orders.service';
import { MenuService } from './menu.service';
@Component({
selector: 'app-orders',
templateUrl: './orders.component.html',
styleUrls: ['./orders.component.css']
})
export class OrdersComponent implements OnInit {
constructor(public ordersService: OrdersService, public menuService: MenuService) {}
ngOnInit(): void {
this.orders = this.ordersService.getOrders();
this.menuService.customerIdUpdate.subscribe(()=>{
this.orders = this.ordersService.getOrders();
})
}
orders: {
id: number,
products: any,
amount: number,
customer: any
}[] = [];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.