Как объявить переменную в шаблоне в Angular


у меня есть следующий шаблон :

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

и хотел бы закончить с :

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

есть ли способ это сделать ?

8 76

8 ответов:

обновление 3

проблема 2451 исправлена в угловой 4.0.0

см. также

обновление 2

это не поддерживается.

есть переменные шаблона, но он не поддерживает произвольных значений. Они могут использоваться только для ссылки на элементы, к которым они применяются, экспортированные имена директив или компонентов и переменные области для структурных директив, таких как ngFor,

Смотрите также https://github.com/angular/angular/issues/2451

обновление 1

@Directive({
  selector: '[var]',
  exportAs: 'var'
})
class VarDirective {
  @Input() var:any;
}

и инициализировать его как

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

или

<div #aVariable="var" [var]="'abc'"></div>

и использовать переменную типа

<div>{{aVariable.var}}</div>

(не проверял)

  • #aVariable создает ссылку на VarDirective (exportAs: 'var')
  • var="abc" создает VarDirective и передает строковое значение "abc" для ввода значения.
  • aVariable.var считывает значение, присвоенное var директивы var вход.

обновление

как @Keith упоминалось в комментариях

это будет работать в большинстве случаев, но это не общее решение, поскольку оно полагается на переменную быть правдивым

так что ответ origin работает, как сказал @Keith. Вот еще один подход. Мы можем просто создать директиву типа *ngIf и называть это *ngVar

ng-var.директива.ТС

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

  context: any = {};

  constructor(private vcRef: ViewContainerRef, private templateRef: TemplateRef<any>) {}

  updateView() {
    this.vcRef.clear();
    this.vcRef.createEmbeddedView(this.templateRef, this.context);
  }
}

С

некрасиво, но:

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

при использовании с асинхронной трубой:

<div *ngFor="let a of [aVariable | async]">
  <span>{{a.prop1}}</span>
  <span>{{a.prop2}}</span>
</div>

вы можете объявить переменные в html-коде с помощью template элемент в угловой 2 или ng-template в угловой 4+.

шаблоны имеют объект контекста, свойства которого могут быть назначены переменным с помощью 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>
-->

вы можете уменьшить количество кода при использовании $implicit свойство объекта контекста вместо пользовательского свойство.

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

объект контекста может быть литеральным объектом или любым другим выражением привязки. Даже трубы, кажется, работают, когда они окружены скобками.

действительные примеры ngTemplateOutletContext:

  • [ngTemplateOutletContext]="{ aVariable: 123 }"
  • [ngTemplateOutletContext]="{ aVariable: (3.141592 | number:'3.1-5') }"
  • [ngTemplateOutletContext]="{ aVariable: anotherVariable }" С let-a="aVariable"
  • [ngTemplateOutletContext]="{ $implicit: anotherVariable }" С let-a
  • [ngTemplateOutletContext]="ctx" здесь ctx это общественная собственность

вот директива, которую я написал, которая расширяет использование параметра 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>

конечно #Local может быть любое допустимое имя локальной переменной.

Я бы предложил следующее:https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138

эта директива позволяет вам написать что-то вроде:

<div *ngLet="'myVal' as myVar">
  <span> {{ myVar }} </span>
</div>

Это намного проще, не нужно ничего дополнительного. В моем примере я объявляю переменную "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>

и метод в компоненте может быть что-то вроде

methodName(parameters: any): any {
  return {name: 'Test name'};
}