Как объявить переменную в шаблоне в Angular
у меня есть следующий шаблон :
<div>
<span>{{aVariable}}</span>
</div>
и хотел бы закончить с :
<div "let a = aVariable">
<span>{{a}}</span>
</div>
есть ли способ это сделать ?
8 ответов:
обновление 3
проблема 2451 исправлена в угловой 4.0.0
см. также
- https://github.com/angular/angular/pull/13297
- https://github.com/angular/angular/commit/b4db73d
- https://github.com/angular/angular/issues/13061
обновление 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'}; }