Angular模板如何实现类似Java try-with-resource的作用域变量绑定?
你要的边界作用域模板变量特性可以通过ngLet指令实现,完全匹配你要的类似Java try-with-resource的局部作用域绑定需求,具体实现方案如下:
方案1:Angular 14.1+ 原生ngLet指令
Angular 14.1之后官方原生提供了*ngLet结构型指令,专门用于声明局部作用域变量,不会触发条件渲染逻辑,不管绑定的表达式返回值是真值还是假值,内部内容都会正常渲染。
用法示例:
<ng-container *ngLet="getData() as data"> <div *ngIf="data.someField"> Yay Some field exist </div> <div> Other content non-dependent on data.someField but on data itself </div> </ng-container>
如果需要叠加额外的布尔判断条件,直接嵌套即可,不会出现语法错误:
<ng-container *ngLet="getData() as data"> <!-- 叠加flag判断逻辑 --> <ng-container *ngIf="flag === true"> <div *ngIf="data.someField"> Yay Some field exist </div> <div> Other content non-dependent on data.someField but on data itself </div> </ng-container> </ng-container>
方案2:低版本Angular自定义ngLet指令
如果你使用的Angular版本低于14.1,可以自己实现一个简单的ngLet指令,代码如下:
// ng-let.directive.ts import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[ngLet]' }) export class NgLetDirective { @Input() set ngLet(value: unknown) { this.context.$implicit = this.context.ngLet = value; if (!this.hasView) { this.viewContainer.createEmbeddedView(this.templateRef, this.context); this.hasView = true; } } private readonly context = { $implicit: null, ngLet: null }; private hasView = false; constructor( private readonly templateRef: TemplateRef<unknown>, private readonly viewContainer: ViewContainerRef ) {} }
之后将该指令声明到你对应的NgModule的declarations数组中,即可和原生ngLet一样使用。
说明
你之前遇到的语法错误、假值不渲染的问题,本质是因为*ngIf是条件渲染指令,核心功能是根据表达式结果决定是否渲染内容,as语法只是它的附带能力,本身不是用来做变量声明的,用它来绑定资源会存在诸多限制,而ngLet是专门为局部变量声明设计的,完全匹配你的使用场景,变量data仅在*ngLet绑定的容器内部生效,外部无法访问,符合边界作用域的要求。
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

