【angular19】入门基础教程(三):关于angular里面的响应式数据入门使用

三个框架,都有响应式数据的概念。在angular里面有专门的叫法,响应式数据叫信号,英文名signal。其他两个框架式没有专门的名字的,统称为动态数据。这点可以说,angular还是太细了,细节值得点赞!!

那么,信号也就是响应式数据在ng里面该怎么使用呢?

实现效果

代码实现

  • 省略无关代码,核心包中引入signal这个api,包装我们需要做成响应式的数据
js 复制代码
import { Component, signal } from '@angular/core';
money = signal(100);

handleChangeAge = () => {
  this.money.update((v) => v + 100);
};
  • 页面上使用
js 复制代码
<p>我银行账户的存款:{{money()}}</p>
<button (click)="handleChangeAge()">改变年龄</button>

注意:

  • 页面上使用的使用,无论是响应式数据还是方法的调用都要加上(),否则页面上无法显示,这点跟其他两个框架略有差别。
  • ng中事件绑定用的是(enventType) = "enventName()"
  • 动态属性用的是[attrName] = "attrName2"

计算属性

根据已有的值计算出新的一个值,这样我们就可以用到computed这个api,这个属性是惰性的,之前的计算结果会被缓存,如果再次读取,就会返回缓存的值,不重新计算。

只有当依赖的值变化后,ng才会知道更新缓存的值了

html 复制代码
<p>我银行账户的存款:{{money()}}</p>
<p>需要换银行的贷款:{{payload()}}</p>

<button (click)="handleChangeAge()">改变存款</button>
js 复制代码
money = signal(100);
payload = computed(() => this.money() * 2);
  • 计算属性是不可写的,也就是无法直接改变,要改变计算属性最直接的就是改变他依赖的值。

  • 直接set是会报错

副作用effect的使用

就是当任何signal变化时,都会触发effect的运行,所以我们可以用effect创建一个副作用:

js 复制代码
effect(() => {
 console.log(`The current count is: ${count()}`);
});

在ts项目中,直接这样写会提示语法错误,需要有返回值。

所以给它赋值下就可以了

或者是在constructor中进行初始化

  • 副作用effect使用推荐的场景

    • 记录正在显示的数据及其更改时间,用于分析或作为调试工具。
    • 使数据与 window.localStorage 保持同步。
    • 添加无法用模板语法表达的自定义 DOM 行为。
    • 对 、图表库或其他第三方 UI 库执行自定义渲染。
  • 手动注入effect

js 复制代码
import {
  Component,
  signal,
  computed,
  effect,
  inject,
  Injector,
} from '@angular/core';

@Component({
  selector: 'UserProfile',
  templateUrl: './index.html',
  styleUrls: ['./index.css'],
})
export class UserProfile {
  // constructor() {
  //   effect(() => {
  //     console.log(`payload, ${this.payload()}`);
  //     console.log('money-------', this.money());
  //   });
  // }

  ngOnInit(): void {
    this.initializeLogging();
  }

  title = '用户信息展示组件';
  userInfo = {
    name: '张三',
    age: 20,
    sex: '男',
    address: {
      city: '北京',
      street: '朝阳区',
    },
  };

  readonly money = signal(100);
  private injector = inject(Injector);
  payload = computed(() => this.money() * 2);

  handleChangeAge = () => {
    this.money.update((v) => v + 100);
  };
  initializeLogging(): void {
    effect(
      () => {
        console.log(`The count is: ${this.money()}`);
      },
      { injector: this.injector }
    );
  }

  reset(): void {
    this.money.set(0);
  }
}
html 复制代码
<button (click)="handleChangeAge()">改变存款</button>
<button (click)="reset()">重置</button>
  • effect取消对某个值的监听untracked这个api包裹就可以了
js 复制代码
effect(
 () => {
    console.log(`The count is: ${untracked(this.money)}`);
  },
  { injector: this.injector }
);
  • 在effect里面销毁定时器等操作
js 复制代码
effect(
(onCleanup) => {
  const timer = setInterval(() => {
    this.money.update((v) => v + 1);
  }, 1000);
  onCleanup(() => clearInterval(timer));
},
{ injector: this.injector }
);
}
相关推荐
码间舞6 分钟前
什么是Tearing?为什么React的并发渲染可能会有Tearing?
前端·react.js
gnip17 分钟前
做个交通信号灯特效
前端·javascript
小小小小宇18 分钟前
Webpack optimization
前端
尝尝你的优乐美20 分钟前
前端查缺补漏系列(二)JS数组及其扩展
前端·javascript·面试
咕噜签名分发可爱多22 分钟前
苹果iOS应用ipa文件安装之前?为什么需要签名?不签名能用么?
前端
她说人狗殊途37 分钟前
Ajax笔记
前端·笔记·ajax
yqcoder1 小时前
33. css 如何实现一条 0.5 像素的线
前端·css
excel1 小时前
Nuxt 3 + PWA 通知完整实现指南(Web Push)
前端·后端
yuanmenglxb20041 小时前
构建工具和脚手架:从源码到dist
前端·webpack
rit84324991 小时前
Web学习:SQL注入之联合查询注入
前端·sql·学习