Html 如何在Angular中声明模板中的变量

Html 如何在Angular中声明模板中的变量,html,angular,Html,Angular,我有以下模板: <div> <span>{{aVariable}}</span> </div> {{aVariable}} 最后,我想: <div "let a = aVariable"> <span>{{a}}</span> </div> {{a} 有办法吗?更新3 问题2451在Angular 4.0.0中固定 另见 更新2 这是不受支持的 有模板

我有以下模板:

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

{{aVariable}}
最后,我想:

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

{{a}

有办法吗?

更新3

问题2451在Angular 4.0.0中固定

另见

更新2

这是不受支持的

有模板变量,但不支持指定任意值。它们只能用于引用应用到的元素、导出的指令或组件名称以及结构指令(如
ngFor
)的范围变量

另见

更新1

@Directive({
  selector: '[var]',
  exportAs: 'var'
})
class VarDirective {
  @Input() var:any;
}
然后像这样初始化它

<div #aVariable="var" var="abc"></div>


并使用如下变量

<div>{{aVariable.var}}</div>
{{aVariable.var}
(未测试)

  • #aVariable
    创建对
    VarDirective
    的引用(
    exportAs:'var'
  • var=“abc”
    实例化
    VarDirective
    ,并将字符串值
    “abc”
    传递给它的值输入
  • aVariable.var
    读取分配给
    var
    指令
    var
    输入的值
丑陋,但:

<div *ngFor="let a of [aVariable]">
  <span>{{a}}</span>
</div>

{{a}
与异步管道一起使用时:

<div *ngFor="let a of [aVariable | async]">
  <span>{{a.prop1}}</span>
  <span>{{a.prop2}}</span>
</div>
myVar$ = of({ hello: '' });

<ng-container *ngIf="myVar$ | async; let var;">
  {{var.hello}}
</ng-container>

{{a.prop1}}
{{a.prop2}}

下面是我编写的一个指令,它扩展了exportAs decorator参数的使用,并允许您将字典用作局部变量

import { Directive, Input } from "@angular/core";
@Directive({
    selector:"[localVariables]",
    exportAs:"localVariables"
})
export class LocalVariables {
    @Input("localVariables") set localVariables( struct: any ) {
        if ( typeof struct === "object" ) {
            for( var variableName in struct ) {
                this[variableName] = struct[variableName];
            }
        }
    }
    constructor( ) {
    }
}
您可以按如下方式在模板中使用它:

<div #local="localVariables" [localVariables]="{a: 1, b: 2, c: 3+2}">
   <span>a = {{local.a}}</span>
   <span>b = {{local.b}}</span>
   <span>c = {{local.c}}</span>
</div>

a={{local.a}
b={{local.b}
c={{local.c}}
当然#local可以是任何有效的局部变量名。

Update 我们可以创建类似于
*ngIf
的指令,并将其称为
*ngVar

ng-var.directive.ts

@Directive({
    selector: '[ngVar]',
})
export class VarDirective {
    @Input()
    set ngVar(context: unknown) {
        this.context.$implicit = this.context.ngVar = context;

        if (!this.hasView) {
            this.vcRef.createEmbeddedView(this.templateRef, this.context);
            this.hasView = true;
        }
    }

    private context: {
        $implicit: unknown;
        ngVar: unknown;
    } = {
        $implicit: null,
        ngVar: null,
    };

    private hasView: boolean = false;

    constructor(
        private templateRef: TemplateRef<any>,
        private vcRef: ViewContainerRef
    ) {}
}
export class AppComponent {
  x = 5;
}

组件。ts

@Directive({
    selector: '[ngVar]',
})
export class VarDirective {
    @Input()
    set ngVar(context: unknown) {
        this.context.$implicit = this.context.ngVar = context;

        if (!this.hasView) {
            this.vcRef.createEmbeddedView(this.templateRef, this.context);
            this.hasView = true;
        }
    }

    private context: {
        $implicit: unknown;
        ngVar: unknown;
    } = {
        $implicit: null,
        ngVar: null,
    };

    private hasView: boolean = false;

    constructor(
        private templateRef: TemplateRef<any>,
        private vcRef: ViewContainerRef
    ) {}
}
export class AppComponent {
  x = 5;
}
  • 如果您不想创建像
    div
    这样的包装器,可以使用
    ng container
  • 查看

    <div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
      <span>{{variable.a}}</span>
      <span>{{variable.b}}</span>
      <span>{{variable.c}}</span>
    </div>
    
    <ng-container *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
      <span>{{variable.a}}</span>
      <span>{{variable.b}}</span>
      <span>{{variable.c}}</span>
    </ng-container>
    
    
    {{variable.a}}
    {{variable.b}}
    {{variable.c}}
    
    正如@Keith在评论中提到的那样


    这在大多数情况下都会起作用,但它不是一个通用的解决方案,因为它 依赖于变量的真实性


    请参阅更新以了解另一种方法。

    您可以使用Angular 2中的
    模板
    元素或Angular 4+中的
    ng模板
    在html代码中声明变量

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

    <ng-template let-a="aVariable" [ngTemplateOutletContext]="{ aVariable: 123 }" [ngTemplateOutlet]="selfie" #selfie>
      <div>
        <span>{{a}}</span>
      </div>
    </ng-template>
    
    <!-- Output
    <div>
      <span>123</span>
    </div>
    -->
    
    上下文对象可以是文本对象或任何其他绑定表达式。当被括号包围时,甚至管道似乎也能工作

    ngTemplateOutletContext
    的有效示例:

    • [ngTemplateOutletContext]=“{aVariable:123}”
    • [ngTemplateOutletContext]=“{aVariable:(3.141592 |编号:'3.1-5')}”
    • [ngTemplateOutletContext]=“{aVariable:anotherVariable}”
      let-a=“aVariable”
    • [ngTemplateOutletContext]=“{$implicit:anotherVariable}”
      let-a一起使用
    • [ngTemplateOutletContext]=“ctx”
      其中
      ctx
      是公共属性
      • 我建议:

        此指令允许您编写如下内容:

        <div *ngLet="'myVal' as myVar">
          <span> {{ myVar }} </span>
        </div>
        
        
        {{myVar}}
        
        它更简单,不需要任何额外的东西。在我的示例中,我声明变量“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>
        
        
        检讨政策摘要
        显示
        隐藏
        
        如果要获取函数的响应并将其设置为变量,可以在模板中使用它,如下所示,使用
        ng container
        避免修改模板

        <ng-container *ngIf="methodName(parameters) as respObject">
          {{respObject.name}}
        </ng-container>
        

        我使用的是angular 6x,最后我使用了下面的代码片段。 我有一个场景,我必须从任务对象中找到用户。它包含用户数组,但我必须选择指定的用户

        <ng-container *ngTemplateOutlet="memberTemplate; context:{o: getAssignee(task) }">
        </ng-container>
        <ng-template #memberTemplate let-user="o">
          <ng-container *ngIf="user">
            <div class="d-flex flex-row-reverse">
              <span class="image-block">
                <ngx-avatar placement="left" ngbTooltip="{{user.firstName}} {{user.lastName}}" class="task-assigned" value="28%" [src]="user.googleId" size="32"></ngx-avatar>
              </span>
            </div>
          </ng-container>
        </ng-template>
        

        我喜欢创建指令的方法(good call@yurzui)

        最后,我找到了一篇中等篇幅的文章,很好地解释了这个问题,并提出了一个自定义的解决方案,该方案在代码更改最少的情况下,非常适合我的用例

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

        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
          }
        }
        
        import{Directive,Input,TemplateRef,ViewContainerRef}来自'@angular/core'
        接口上下文{
        小程序:T | null
        }
        @指示({
        选择器:“[appLet]”,
        })
        导出类指令{
        私有_context:LetContext={appLet:null}
        构造函数(_viewContainer:ViewContainerRef,_templateRef:templateRef){
        _viewContainer.createEmbeddedView(_templateRef,this._上下文)
        }
        @输入()
        设置小程序(值:T){
        此._context.appLet=值
        }
        }
        
        我的主要变化是:

        • 将前缀从“ng”更改为“app”(您应该使用应用程序的自定义前缀)
        • appLet:T
          更改为
          appLet:T|null
        不知道为什么Angular团队不仅制定了官方的ngLet指令,还制定了其他指令

        原始源代码归功于@austinmaterne

        简短的答案,它对某人有帮助

        • 模板引用变量通常引用一个模板中的DOM元素 模板
        • 也可参考角度或腹板组件和指令
        • 这意味着您可以轻松访问模板中的任何位置的变量

        • 使用哈希符号(#)声明引用变量
        • 可以将变量作为事件的参数传递

        *但是,您可以使用ViewChild装饰器在组件中引用它

        import {ViewChild, ElementRef} from '@angular/core';
        
        引用组件内部的firstNameInput变量

        @ViewChild('firstNameInput') nameInputRef: ElementRef;
        
        之后,您可以使用
        <ng-container *ngTemplateOutlet="memberTemplate; context:{o: getAssignee(task) }">
        </ng-container>
        <ng-template #memberTemplate let-user="o">
          <ng-container *ngIf="user">
            <div class="d-flex flex-row-reverse">
              <span class="image-block">
                <ngx-avatar placement="left" ngbTooltip="{{user.firstName}} {{user.lastName}}" class="task-assigned" value="28%" [src]="user.googleId" size="32"></ngx-avatar>
              </span>
            </div>
          </ng-container>
        </ng-template>
        
        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
          }
        }
        
          show(lastName: HTMLInputElement){
            this.fullName = this.nameInputRef.nativeElement.value + ' ' + lastName.value;
            this.ctx.fullName = this.fullName;
          }
        
        import {ViewChild, ElementRef} from '@angular/core';
        
        @ViewChild('firstNameInput') nameInputRef: ElementRef;
        
        myVar = { hello: '' };
        
        <ng-container *ngIf="myVar; let var;">
          {{var.hello}}
        </ng-container>
        
        myVar$ = of({ hello: '' });
        
        <ng-container *ngIf="myVar$ | async; let var;">
          {{var.hello}}
        </ng-container>
        
        <ng-template [ngVar]="variable">
        your code
        </ng-template>
        
         <ng-container *ngIf="lineItem.productType as variable">
               {{variable}}
         </ng-container>
        
         <ng-container *ngIf="'ANY VALUE' as variable">
               {{variable}}
          </ng-container>