Angular不是真正的MVVM框架,因其组件类无自动通知机制,依赖Zone.js触发的周期性变更检测而非观察者模式;推荐采用组件+服务+Observable的数据流方案。
Angular 不是 JavaScript 的一个特性或内置模式,它是一个由 Google 维护的独立前端框架,用 TypeScript 编写,运行时依赖 JavaScript 引擎。它不是“JavaScript 的 Angular”,而是“基于 JavaScript/TypeScript 构建的 Angular 框架”。
Angular 采用的也不是严格意义上的 MVVM(Model-View-ViewModel),而是基于组件的、带有单向数据流和变更检测机制的架构;它的模板绑定看起来像 MVVM,但底层实现和设计哲学差异很大。
Angular 模板中写的 {{user.name}} 或 [ngModel]="user.name" 看似 ViewModel 绑定,实际背后是:变更检测(Change Detection)+ 指令系统 + Zone.js 补丁。
{{}}、[prop]、(event))在编译阶段被解析为 Binding 对象,挂载到组件视图节点上setTimeout、Promise.then、addEventListener),触发 ApplicationRef.tick(),启动变更检测CheckOnce 策略:从根组件向下逐层比对 oldValue !== newValue,仅更新脏值对应 DOMngModel 是双向绑定语法糖,本质是同时设置 [ngModel](输入)和监听 (ngModelChange)(输出)
@Component({
template: `
Hello {{ userName }}
`
})
export class MyComponent {
userName = 'Alice';
}
这看起来像 MVVM,但 userName 不是 ViewModel 实例,只是普通类属性;没有自动通知机制(如 Knockout 的 observable),全靠 Angular 运行时周期性拉取比对。
MVVM 的核心是 ViewM
odel 层通过 观察者模式主动通知 View 更新(如 WPF、Knockout),而 Angular 的 ViewModel(即组件类)是被动的:
INotifyPropertyChanged 类接口this.user.name = 'Bob' 不会立刻更新视图,要等下一次变更检测周期this.user.profile.city = 'Shanghai'),除非使用 OnPush + Immutable + Object.assign 替换整个引用async 管道能“模拟”响应式,但底层仍是订阅 Observable 后手动调用 markForCheck()
Angular 官方推荐以 组件 + 服务 + 可观察对象(Observable) 构建数据流,尤其搭配 RxJS:
BehaviorSubject 或 Store(如 NgRx),组件只负责订阅与渲染async 管道自动订阅/销毁:{{ data$ | async }},避免手动 subscribe/unsubscribe
ChangeDetectionStrategy.OnPush,强制组件只在 @Input 引用变化或显式触发时检查this.user = { ...this.user, name: 'New' };
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
template: `{{ user$ | async | json }}`
})
export class UserComponent {
user$ = this.userService.currentUser$; // Observable
}
Angular 的模板响应能力来自框架层的调度与约束,不是语言或模式本身赋予的。真正容易被忽略的是:变更检测不是免费的,OnPush 不是银弹,Zone.js 的补丁有开销,Observable 订阅不清理会导致内存泄漏——这些细节比“是不是 MVVM”更能决定项目是否稳健。