我正在测试Angular 为16的信号,根据我的理解,当我禁用zone.js并调用signal.update()时,应该用新值更新视图.但事实并非如此.请帮我弄明白为什么.

双手

platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: 'noop' })
    .catch(err => console.error(err));

App.component.ts

@Component({
    selector: 'app-root',
    template: '
        <h1>{{ title() }}</h1>
        <button (click)="click()">Change</button>
    ',
})
export class AppComponent {
    title = signal('Hello');

    click(): void {
        this.title.update((value) => value + "!!");
    }
}

我期待在点击按钮后,"标题"的值将从"Hello"更新为"Hello!!".它不会更新.

推荐答案

TL;DR: Because Angular still uses zone.js in order to trigger change detection.

Zone.js在幕后包装了一系列浏览器API,以便检测页面上何时发生事件(它会查找特定类型的事件,有关详细信息,请参阅the Angular docs about zones).它不会通知ANGLE到底发生了什么事件,但它会说某处的某个值可能发生了变化.然后,ANGLING启动循环遍历整个组件树的更改检测,判断所有组件的更改.如果启用了ChangeDetectionStrategy.OnPush,则它可以更高效,只判断树中可能已更改的组件.

这就是为什么您会看到您的函数被执行以正确地更新信号.缺少的环节是,zone.js将检测到这一点,并通知Angel某些内容已更新,以便启动更改检测.如果您要添加一个调用来手动触发更改检测,那么它应该会让您的示例再次工作.

在能够从兼容的应用程序中完全删除zone.js的道路上,信号只是第一步.在Angel的GitHub资源库上有一个(now complete) RFC讨论基于信号的组件,这将是朝着能够实现无地带的Angel应用程序又迈进了一步.改变ANGLE的所有基础设施只需要一段时间,因为zone.js是ANGLE当前工作方式的基础部分.

这里有一个slightly-old article讨论了更多的zone.js及其在Angular 变化检测过程中的作用(它仍然非常相关).

Angular相关问答推荐

根据Angular中的构建来卸载独立组件

RFDC.CommonJS或AMD依赖项可能会导致优化救助ANGURAL PROCEMENT with ngx-charts lib

Angular 16路卫单元测试可观察到的SpyObj属性

Angular 16+使用ngTemplateOutlet有条件地呈现几个模板中的一个

如何捕获生命周期方法中抛出的Angular组件错误?

出错后可观察到的重用

显示用户名-Angular

npm install命令在基本Angular 应用程序的天蓝色构建管道中失败

错误:在@angular/core中找不到导出ɵivyEnabled(导入为ɵivyEnabled)

模块内的命名路由出口 - 路径匹配但内容未加载

如何禁用特定数据集图表js的默认标签

Angular 2: Debounce(ngModelChange)?

初始化所有子类后的Angular 2生命周期钩子是什么?

Angular 4:InvalidPipeArgument:管道AsyncPipe的[object Object]

Angular 4 设置下拉菜单中的选定选项

Angular 2 中的 $implicit 是什么?

Angular 2 中的 OnChanges 和 DoCheck 有什么区别?

Angular 5 测试:如何获取对子组件的引用

Angular 5 和material - 如何从 SnackBar 组件更改背景 colored颜色

NPM 脚本 start退出,但未指示 Angular CLI 正在侦听请求