Introduction

我已经创建了一个共享表组件,该组件使用Angular material 根据数据和列配置来呈现表.该组件具有字符串和数字数据类型的默认模板,但用户应该能够为任何列提供自定义模板.

我有一个有三条路由的示例应用程序:Home、Page1(有一个表格)和Page2(也有一个表格).但是,当用户导航到表页时,表在第一次加载时不会完全呈现.只有在用户再次导航到同一页后,它才会完全呈现.我怀疑这是由于第一次呈现的生命周期和缺少模板所致,这会引发错误:ExpressionChangedAfterItHasBeenCheckedError.

What I expect

我希望该表在第一次加载时完全呈现,没有任何错误.

另外,我还有一个附带的问题:既然抛出了ExpressionChangedAfterItHasBeenCheckedError,这个问题是否有可能在Prod中自行解决?

Example

我已经在Stackblitz上复制了这个问题,但要完全体验这个问题,请访问这个完整的页面:https://stackblitz-starters-5gez6t.stackblitz.io/

这是Stackblitz的编辑链接:https://stackblitz.com/edit/stackblitz-starters-5gez6t

推荐答案

简短的回答

我怀疑这是由于生命周期和缺乏模板 首先渲染,

你说的完全正确.您只需更新您的@ViewChild个修饰符,使其使用{static: true}而不是{static: false}

更新的Stackblitz编辑器视图:https://stackblitz.com/edit/stackblitz-starters-co2me9?file=src%2Ftable%2Ftable.component.ts

更新的Stackblitz应用程序共享链接:https://stackblitz-starters-co2me9.stackblitz.io

Long answer: Lifecycle hooks and @ViewChild {static: true/false}

根据docs,ViewChild修饰符元数据的static: boolean属性指示何时在更改检测之前(在ngOnInit中)或在更改检测之后(在ngAfterViewInit中)解析视图查询,并且其缺省值为FALSE.

我建议您总是try 使用{static: true},除非您绝对不能使用.这种方法的主要好处是不需要使用额外的生命周期挂钩(如ngAfterViewInit).如果您的元素是动态呈现的(例如:组件模板中的元素位于*ngIf或*ngFor内),则不能使用static:true.换句话说,如果元素不是动态的,那么它就是静态的.

在本例中,您的所有默认列模板都是静态(而不是动态)ng模板,它们位于表的底部.组件.html,因此您应该用static:true来引用它们

您还可以在现有的日志(log)中看到,您已经在其中添加了大多数组件生命周期挂钩(以及getTemplate个组件函数中的日志(log)).组件模板中使用了getTemplate函数,它将在ngAfterViewInit钩子之前运行该函数,并且因为您当前使用的是static:false,所以要记录的ViewChild引用在ngAfterViewInit内的LOG语句之前是未定义的.

Side Answer RE: ExpressionChangedAfterItHasBeenChecked

对于docs,这是一个仅在开发模式下引发的错误,特别是由在开发模式下运行的额外更改检测周期引起的.因此,只要您使用生产配置(例如:ng build --prod)构建和部署应用程序,您就不会看到错误.

然而,在应用程序的部署版本中,你不会在控制台中看到这些错误日志(log),这并不意味着你可以在开发过程中简单地忽略它们.您看到的这个特定的错误仍然会发生,只是您不会看到ExpressionChangedAfterItHasBeenChecked错误.

Angular相关问答推荐

如何使用ANGLING HTTP.POST并将类型更改为键入的回复?

路由在全局导航中总是给我/甚至使用相对路径

仅在展示时使用垫式步进器

判断哪个Angular 信号导致了影响

为什么在回调完成之前,可观察对象会返回?

AG网格Angular 快捷菜单调用函数

无效的ICU消息.缺少';}';|Angular material 拖放(&A)

在Angular 17的本地服务应用程序时禁用SSR

Angular 信号 在 effect() 中使用 debounce

Angular 13 - 使用 PUT 时出现 400 错误(错误请求)

最新版本的 Chrome ERR_TIMED_OUT

在ionic 5中获取url传递的参数

将环境变量传递给Angular 库

错误 TS1086:无法在 Angular 9 的环境上下文中声明访问器

Angular-CLI 代理到后端不起作用

如何在 Angular 2 中创建可重用的动画

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

如何在 ngFor angular 2 内部使用 track

angular2中的httpinterceptor类似功能是什么?

Angular2 Routerlink:添加查询参数