前言
Angular 在 v18.1 推出了 Template 新语法 @let。
这个 @let 和上一篇教的 Control Flow @if, @for, @swtich, @defer 语法上类似,但是用途却差很多。
如果要给它们分类的话,@if @for @switch 可以算一类,@defer 独立一类,@let 又是独立一类,总之大家不要混淆就是了。
没有 @let 的日子
我们先来看看没有 @let 的日子里,我们都遇到了哪些不方便。
Long path access
App 组件- export class AppComponent {
- person = signal({
- name: 'Derrick',
- address: {
- country: 'Malaysia',
- state: 'Johor',
- postalCode: '81300'
- }
- })
- }
复制代码 有一个 person 对象,它里面又有一个 address 对象。
App Template- <p>{{ person().name }}</p>
- <p>{{ person().address.country }}</p>
- <p>{{ person().address.state }}</p>
- <p>{{ person().address.postalCode }}</p>
复制代码 上述代码最大的问题就是 person().address 一直重复,代码很长,很丑。
倘若在 JS 里的话,我们一定会 declare 一个 variable 把 address 对象装起来,像这样访问- const address = person.address;
- console.log(address.country);
- console.log(address.state);
- console.log(address.postalCode);
复制代码 没有一直重复 person.address 干净多了。
但是在 Template 里,我们无法 declare variable,能 declare variable 的只有组件- export class AppComponent {
- person = signal({
- name: 'Derrick',
- address: {
- country: 'Malaysia',
- state: 'Johor',
- postalCode: '81300'
- }
- });
- address = computed(() => this.person().address);
- }
复制代码 App Template- <p>{{ person().name }}</p>
- <p>{{ address().country }}</p>
- <p>{{ address().state }}</p>
- <p>{{ address().postalCode }}</p>
复制代码 虽然 path 是短了,但是组件却为了 View 而多了一个 property,这样的职责分配合理吗?
再说,如果是在 @for 里面- @for (person of people(); track person.name) {
- <p>{{ person.name }}</p>
- <p>{{ person.address.country }}</p>
- <p>{{ person.address.state }}</p>
- <p>{{ person.address.postalCode }}</p>
- }
复制代码 组件 property 也无法解决这个问题丫。
the hacking way
有些人会用 hacking way 来做到这一点,像这样- @for (person of people(); track person.name) {
- <p>{{ person.name }}</p>
- @if (person.address; as address) {
- <p>{{ address.country }}</p>
- <p>{{ address.state }}</p>
- <p>{{ address.postalCode }}</p>
- }
- }
复制代码 虽然 path 是短了,但是 @if 是这样用的吗?这种不顺风水的用法,随时会掉坑里的,忌讳啊。
Async pipe
App 组件- export class AppComponent {
- value$ = of('hello world');
- }
复制代码 有一个 value stream。
App Template- <header>
- <p>{{ value$ | async }}</p>
- </header>
- <main>
- <p>body</p>
- </main>
- <footer>
- <p>{{ value$ | async }}</p>
- </footer>
复制代码 我要在 header 和 footer 显示这个 value。
上述代码有两个问题:
- 两次 pipe async 会导致 value stream 被 subscribe 两次。
如果这个 value 需要发 ajax,那它就会发 2 次 ajax。
- 不管是使用什么 pipe 都好,每一次使用 value 都要重复同样的 pipe,这就不合理。
而,倘若我们把职责交给组件,那组件就需要使用 pipe,这样也不合理。
总之,怎样都不合理,这就是一个设计失误。
总结
Angular 对 Template 限制太多了,以至于许多简单的 View 逻辑无法在 Template 里完成,必须转交给不合适的组件,或者大费周章的指令去完成。
这也是为什么这个 issue 能常年霸榜
幸好,在经历了 2657 个日夜
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |