Angular杂项
什么操作会触发Angular执行change detection?
这个问题一直没有搞明白,有待进一步研究。
https://angular.io/guide/change-detection
https://www.youtube.com/watch?v=-tB-QDrPmuI
这个问题,现在大概了解了一些,Angular内部使用Zone.js来实现change detection,Zone.js对所有异步操作都进行了monkey patch,当有异步操作发生时,Angular会自动进行更新检测。所以这些动作会出发Angular执行change detection:
- setTimeout/setInterval
- XMLHttpRequest/fetch
- EventListener: click, mouseover, keydown, …
- Promise.then
- Async/Await
Change detection相关参考资料
- https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/ - 尚未阅读。
- https://hackernoon.com/everything-you-need-to-know-about-change-detection-in-angular-8006c51d206f - 这个比较老了,用的还是Angular4.0的源码讲解的。
- https://stackoverflow.com/questions/42643389/why-do-we-need-ngdocheck/42807309#42807309 - ngDoCheck的作用。
Content
在AOT编译器下,Private变量无法绑定到模板中。
如果在组件中定义了一个私有变量,是不能使用双括弧绑定到模板中的,比如下面的代码:
1 | ({ |
1 | <p>{{count}}</p> |
这样写是不行的,因为在AOT编译器下,私有变量会被删除,所以无法绑定到模板中,如果想要绑定到模板中,需要将变量定义为公共变量,或者使用get
方法,如下:
1 | ({ |
1 | <p>{{count}}</p> |
或者使用getCount()方法,如下:
1 | ({ |
1 | <p>{{getCount()}}</p> |
AOT vs JIT
Monkey Patching
In computer programming, monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. It is used to extend or modify the runtime code of dynamic languages such as Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, and Lisp without altering the original source code. - Wikipedia
Angular找不到selector对应的组件时,不会报错。
如果你在Angular template中使用了一个选择器,但是这个选择器没有对应任何组件,那么Angular不会报错,只会将选择器当作一个普通的HTML标签处理。这个问题在开发过程中很容易出现,因为Angular不会报错,所以很难发现。
ng-repeat
vs ngFor
ng-repeat
是AngularJS中的指令,用于循环遍历数组或对象。ngFor
是Angular中的指令,用于循环遍历数组或对象。
Angular中的viewProviders和providers
竟然还有viewProvider?真是孤陋寡闻了。
基于配置的换肤方案
因为Angular的模板和样式是在Component元数据中指定的,所以我们可以定义一个变量用来控制模板和样式的变化,从而实现换肤功能。
首先:我们在config
目录下新建一个theme.ts
文件,用来存放主题相关的配置。这里我们定义一个USE_LIGHT_THEME
变量,用来控制是否使用浅色主题。
1 | // config/theme.ts |
然后:我们在app.component.ts
中引入USE_LIGHT_THEME
变量,根据这个变量的值来选择不同的模板和样式。
1 | // app.component.ts |
以上就是一个简单的实现方式,通过更改USE_LIGHT_THEME
的值,就可以实现换肤功能。使用这种方法时,我们可以为已有的项目添加换肤功能,而不需要修改原有的代码,只需为每个组件添加一个额外的模板和样式文件即可。(有的甚至只需要添加一个样式文件就行了)。
如何让Angular每五分钟进行一次更新检测?
为什么会有如此奇怪的需求呢,现实中还真有。比如我们使用websocket来实时更新数据,但是websocket的数据更新不会触发Angular的change detection,所以我们需要定时调用ChangeDetectorRef.detectChanges()
方法来手动触发更新检测。
这里的做法是首先使用ChangeDetectorRef.detach()
方法来暂时关闭自动更新检测,然后使用setInterval()
方法每隔5秒调用一次ChangeDetectorRef.detectChanges()
方法来手动触发更新检测。
1 | constructor(private ref: ChangeDetectorRef) { |
HostBinding主要用来做什么?
HostBinding
装饰器用来绑定宿主元素的属性,比如下面的例子,我们使用HostBinding
装饰器将class
属性绑定到app-root
元素上。
1 | ({ |
这样就相当于在app-root
元素上添加了一个class="app-root"
属性。
MDC
MDC = Material Design Components.
Angular challenges
https://angular-challenges.vercel.app/guides/getting-started/
Angular interview.
Angular zone.js
- https://angular.love/from-zone-js-to-zoneless-angular-and-back-how-it-all-works
- https://dev.to/vivekdogra02/angular-zonejs-change-detection-understanding-the-core-concepts-16ek
- https://medium.com/@krzysztof.grzybek89/how-runoutsideangular-might-reduce-change-detection-calls-in-your-app-6b4dab6e374d
- https://medium.com/@sehban.alam/what-is-zone-js-in-angular-e0029c21c32f
- https://www.youtube.com/watch?v=pGBh5oNB2wE
UI framework
- PrimeNg - https://primeng.org/
- Angular Material - https://material.angular.io/
- DevUI - https://devui.design/home
Angular Form
- Template-driven form
- Reactive form
[(ngModel)] 使用双向绑定必须先导入FormsModule模块。
1 | import { FormsModule } from '@angular/forms'; |
如何查看Angular编译后的结果?
可以使用ngc
命令,详情看这里:https://zdd.github.io/2024/05/21/angular-ngc/
各种Ref
- ChangeDetectorRef - 构造函数注入,用于手动触发更新检测。
- ElementRef - 构造函数注入,用于获取当前元素的引用, 常用于自定义指令。
- ComponentRef - 用于获取组件实例。
- ViewContainerRef - 构造函数注入,用于动态创建组件。
- TemplateRef - 构造函数注入,用于动态创建组件。
- EmbeddedViewRef -
- ViewRef
发现一个Angular宝藏
- https://angular.love/ - 有空整个通读一下吧,质量非常之高!
- https://angular-university.io/ - 这个质量就一般了。