typescript Angular 15:每次值改变时调用函数

5lhxktic  于 2023-01-06  发布在  TypeScript
关注(0)|答案(1)|浏览(174)

我们的教授要求我们用以下组件构建一个简单的电子商务应用程序:客户、订单、菜单(导航栏)和购物车。我们需要根据从导航栏下拉菜单中选择的客户在前端显示订单,如图所示:

一旦我们选择了一个客户,它的ID就会被分配给一个变量,然后它就会被用来根据客户ID加载订单(多亏了一个名为getOrdersByCustomerId的端点),然后它为每一个生成一张卡片。到目前为止一切顺利。问题是,该函数在订单组件中只调用一次,初始值为0,我们不知道如何在每次ID更改时进行动态调用。下面是代码:

  • 菜单服务(其中选择了客户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);
  }
}
  • HTML菜单组件
<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)="-->
  • 订单服务(我们需要id来显示订单)
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
  }[] = [];

}
  • HTML订单组件
<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才一周,这些脚本中可能有很多不好的做法,很抱歉。为了简洁起见,我省略了客户端组件,因为它与问题无关(它工作正常,ID被正确检索)。提前感谢您的帮助!

holgip5t

holgip5t1#

看起来当客户改变时,只有customerId被更新,其他的什么都没有。触发新的后端调用的一种方法是当customerId被更新时发出一个事件。然后你可以在order组件中监听它并触发新的后端调用。
在您的菜单中:

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
  }[] = [];

}

相关问题