Angular 中的状态管理

发布于 2023-07-30 12:07:42 字数 2826 浏览 40 评论 0

由于之前一直用的是 Vue 和 React,对 Angular 还不是很熟悉,对于 Vue 或者 React 来说,每一个单独的组件都有它自身的状态,例如 Vue:

export defaut {
    data() {
        return {
            message: "hello world",
        }
    }
}

它这个状态是响应式的,通过更改 message 的值,能够实时更新页面上对应的组件。

而 Angular 的组件自身是没有状态,需要额外构建一个 service ,通过依赖注入的方式将状态注入到组件中,例如构建一个 ProductService :

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private cart = [];

  constructor() { }

  add(product) {
    this.cart.push(product);
  }

  items() {
    return this.cart;
  }

  clear() {
    this.cart = [];
  }

  pop() {
    this.cart.pop();
  }

  delete(index) {
    this.cart.splice(index, 1);
  }
}

将 service 注入到组件中:

import { Component, OnInit } from '@angular/core';
import {ProductService} from '../product.service';
import ProductEntity from '../product/product.entity';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.scss']
})
export class CartComponent implements OnInit {

  products = [];

  constructor(
    private productService: ProductService
  ) {
    this.products = this.productService.items();
  }

  ngOnInit() {

  }

  addProduct() {
    console.log('add a product');
    const product = new ProductEntity();
    product.title = 'title';
    product.vendor = 'vendor';
    product.amount = 2;
    product.price = 10.34;
    product.image = 'https://www.wenjiangs.com/wp-content/uploads/2023/docimg21/67-zpxsgdgbh0r.jpg';

    this.productService.add(product);
  }
  rmProduct() {
    console.log('remove a product');
    this.productService.pop();
  }
  get total() {
    let totalPrice = 0;
    this.products.forEach(product => {
      totalPrice += product.amount * product.price;
    });
    return totalPrice;
  }
}

这种方式既有好处也有坏处,首先 Angular 这种方式写起来比较繁琐,因为每个组件都要添加对应的 service (这里针对有状态组件而言),因此 Angular 不适合构建大量粒度比较细的组件,而 Vue 和 React 在这方面是强项,不过这种方式也有好处,就是状态与组件分离了,那么组件之间的消息传递就会变得十分简单,不像 Vue, 它如果需要在完全不相关的组件之间传递数据,需要引入消息总线(event bus)或者 Vuex,因为它们的组件之间的状态是独立的,而 Angular 只需要将对应的 service 通过依赖注入注入到不同组件即可。

一些注意项:

获取组件数组索引

 <div class="" *ngFor="let product of products; index as i">
    <app-product [product]="product" [index]="i"></app-product>
  </div>

获取特定组件的 event ,例如 input 框:

    <div class="amount">
          <input type="number" value="{{product.amount}}" (change)="changeAmount(index, $event)">
    </div>

这里没有使用双向绑定是因为需要同步更新 service 中的状态。

以上代码的另外一种推荐写法:

 <div class="amount">
          <input type="number" value="{{product.amount}}" #amount (change)="changeAmount(index, amount.value)">
 </div>

应该尽可能使用第二种写法。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

走过海棠暮

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文