我有以下模板:

<div>
  <span>{{aVariable}}</span>
</div>

并希望以:

<div "let a = aVariable">
  <span>{{a}}</span>
</div>

有办法吗?


当前回答

你可以使用Angular 2中的template元素或Angular 4+中的ng-template在html代码中声明变量。

模板有一个上下文对象,它的属性可以使用let绑定语法分配给变量。注意,您必须为模板指定一个出口,但它可以是对模板本身的引用。

<ng-template #selfie [ngTemplateOutlet]="selfie"
    let-a="aVariable" [ngTemplateOutletContext]="{ aVariable: 123 }">
  <div>
    <span>{{a}}</span>
  </div>
</ng-template>

<!-- Output
<div>
  <span>123</span>
</div>
-->

您可以通过使用context对象的$implicit属性而不是自定义属性来减少代码量。

<ng-template #t [ngTemplateOutlet]="t"
    let-a [ngTemplateOutletContext]="{ $implicit: 123 }">
  <div>
    <span>{{a}}</span>
  </div>
</ng-template>

上下文对象可以是文字对象或任何其他绑定表达式。其他有效例子:

<!-- Use arbitrary binding expressions -->
<ng-template let-sum [ngTemplateOutletContext]="{ $implicit: 1 + 1 }">

<!-- Use pipes -->
<ng-template let-formatPi [ngTemplateOutletContext]="{ $implicit: 3.141592 | number:'3.1-5' }">

<!-- Use the result of a public method of your component -->
<ng-template let-root [ngTemplateOutletContext]="{ $implicit: sqrt(2116) }">

<!--
    You can create an alias for a public property of your component:
    anotherVariable: number = 123; 
-->
<ng-template let-aliased [ngTemplateOutletContext]="{ $implicit: anotherVariable }">

<!--
    The entire context object can be bound from a public property:
    ctx: { first: number, second: string } = { first: 123, second: "etc" }
-->
<ng-template let-a="first" let-b="second" [ngTemplateOutletContext]="ctx">

其他回答

对某人有帮助的简短回答

模板引用变量经常引用DOM元素 模板。 也可以参考angular或web组件和指令。 这意味着您可以轻松地访问模板中的任何地方的变量

使用哈希符号(#)声明引用变量 是否能够将变量作为事件的参数传递

  show(lastName: HTMLInputElement){
    this.fullName = this.nameInputRef.nativeElement.value + ' ' + lastName.value;
    this.ctx.fullName = this.fullName;
  }

但是,你可以使用ViewChild装饰器在你的组件中引用它。

import {ViewChild, ElementRef} from '@angular/core';

在Component中引用firstNameInput变量

@ViewChild('firstNameInput') nameInputRef: ElementRef;

之后,你可以在组件中的任何地方使用this.nameInputRef。

使用ng-template

对于ng-template,略有不同,因为每个模板都有自己的一组输入变量。

https://stackblitz.com/edit/angular-2-template-reference-variable

它简单得多,不需要任何额外的东西。在我的例子中,我声明变量“open”,然后使用它。

   <mat-accordion class="accord-align" #open>
      <mat-expansion-panel hideToggle="true" (opened)="open.value=true" (closed)="open.value=false">
        <mat-expansion-panel-header>
          <span class="accord-title">Review Policy Summary</span>
          <span class="spacer"></span>
          <a *ngIf="!open.value" class="f-accent">SHOW</a>
          <a *ngIf="open.value" class="f-accent">HIDE</a>
        </mat-expansion-panel-header>
        <mat-divider></mat-divider>
        <!-- Quote Details Component -->
        <quote-details [quote]="quote"></quote-details>
      </mat-expansion-panel>
    </mat-accordion>

在Angular 12中:

  <div *ngIf="error$ | async as error">
     <span class="text-warn">{{error.message}}</span>
   </div>

我喜欢创建一个指令来做这件事的方法(很好的调用@yurzui)。

最后我在Medium上找到了一篇文章,Angular的“let”指令很好地解释了这个问题,并提出了一个自定义的let指令,它在我的用例中工作得很好,代码更改很少。

以下是要点(在发布时)和我的修改:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'

interface LetContext <T> {
  appLet: T | null
}

@Directive({
  selector: '[appLet]',
})
export class LetDirective <T> {
  private _context: LetContext <T> = { appLet: null }

  constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef <LetContext <T> >) {
    _viewContainer.createEmbeddedView(_templateRef, this._context)
  }

  @Input()
  set appLet(value: T) {
    this._context.appLet = value
  }
}

我的主要改变是:

将前缀从'ng'更改为'app'(你应该使用你的应用程序的自定义前缀是什么) 将appLet: T更改为appLet: T | null

不知道为什么Angular团队还没有发布一个官方的ngLet指令。

原始源代码归功于@AustinMatherne

我试图做一些类似的事情,看起来这个问题已经在angular的新版本中得到了解决。

    <div *ngIf="things.car; let car">
      Nice {{ car }}!
    </div>
    <!-- Nice Honda! -->