引言
一 signal
是什么???
What are signals?
A signal is a wrapper around a value that notifies interested consumers when that value changes. Signals can contain any value, from primitives to complex data structures.
You read a signal's value by calling its getter function, which allows Angular to track where the signal is used.
Signals may be either writable or read-only.
译:信号是一个值的包装器,当该值发生变化时通知感兴趣的消费者。信号可以包含任何值,从原语到复杂的数据结构。
由上可知:
- signal 有两种类型, 一种是可写的WritableSignal,可改变值,一种是可读的Signal,不可改变值。
- 被signal 包装的值, 那个值的类型不受限制。
- 3 是属于订阅者模式,当值发生变化会通知消费者。
signal信号
可写的信号
import {Component, effect, OnInit, signal, WritableSignal} from '@angular/core';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
imports: [RouterOutlet],
templateUrl: `
<p>The count is: {{ count() }}</p>
<button (click)="increment()">Increment</button>
`,
styleUrl: './app.component.css'
})
export class AppComponent implements OnInit {
// 创建 signal()
count: WritableSignal<number> = signal(0);
ngOnInit(): void {
// 改变值 .set()
this.count.set(100);
console.log(`The current count is: ${this.count()}`);
}
increment() {
// 使用该.update()操作根据前一个值计算出一个新值:
this.count.update(v => v + 1);
}
// 订阅
effect = effect(() => {
// 值每变化一次,执行一次
// 可在此处作一些逻辑判断
console.log(`effect: ${this.count()}`);
});
}
计算信号(只可读的信号)
计算信号其值来自其他信号。可以使用computed函数定义计算信号并指定派生函数。 doubleCount依赖于count()。
const count: WritableSignal<number> = signal(0);
const doubleCount: Signal<number> = computed(() => count() * 2);
计算信号的依赖性是动态的,可有可无。
const showCount = signal(false);
const count = signal(0);
const conditionalCount = computed(() => {
if (showCount()) {
return `The count is ${count()}.`;
} else {
return 'Nothing to see here!';
}
});
signal 和 RxJS 的区别是什么?
特点 | Signal | RxJS |
---|---|---|
关注点 | 组件内部状态 | 异步数据流 |
复杂度 | 相对简单 | 功能强大,但学习曲线陡峭 |
性能 | 通常性能更好,尤其是在频繁更新的场景下 | 性能取决于使用的操作符和数据量 |
适用场景 | 组件内部状态管理,简单的异步操作 | 复杂的异步操作,构建数据流应用程序 |
如何在组件销毁时取消 effect 的订阅?
effect()返回的是一个EffecrRef类型的对象,可调用.destory()方法对其进行销毁。
二 component 组件
impotrs
组件不再强制依赖 NgModule,可以独立存在。
在组件@Component 装饰器中有imponts, 可导入组件,指令,管道,模块。这是使用angular 19 版本生成的组件默认standalone为true, 以前是standalone默认为false。
如果设置standalone为false,组件仍然依赖 NgModule
selector 选择器
Angular 指令注解的属性解释 看这篇文章就够了。
Routing 路由
angular 创建新项目后会自动创建两个文件 app.config.ts 和app.routers.ts, 可配置使用路由
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import {provideRouter, Routes} from '@angular/router';
import {FirstComponent} from './first/first.component';
import {ViewComponent} from './view/view.component';
const routes: Routes = [
{
path: 'first',
component: FirstComponent,
children: [
{
path: ':id',
component: ViewComponent,
},
],
},
{
path: 'second',
loadComponent: () => import('./second/second.component').then(m => m.SecondComponent),
}
];
export const appConfig: ApplicationConfig = {
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]
};
RouterLink
routerLink 可接收数组, /path是路径,剩下的分别是参数
<a [routerLink]="['/path', param1, param2, ...]">链接文本</a>
三 设置HttpClient
不再是以前那样导入HttpClientMoudule。有是由provideHttpClient(),提供。
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
]
};
总结
1 有异步操作的话,可考虑使用signal, 可学习一下结合使用signal和RxJS
2 组件单独化了,不用写export了。
3 以前的模块,HttpClientModule, RouterModule等,改为provideHttpClient(),provideRouter(routes)形式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。