我有以下模板:
<div>
<span>{{aVariable}}</span>
</div>
并最终以:
<div "let a = aVariable">
<span>{{a}}</span>
</div>
有办法吗?
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
我有以下模板:
<div>
<span>{{aVariable}}</span>
</div>
并最终以:
<div "let a = aVariable">
<span>{{a}}</span>
</div>
有办法吗?
<div *ngIf="{name:'john'} as user1; let user"> <i>{{user1|json}}</i> <i>{{user|json}}</i> </div>
Answers:
我们可以像这样创建指令*ngIf
并调用它*ngVar
ng-var.directive.ts
@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);
}
}
通过此*ngVar
指令,我们可以使用以下命令
<div *ngVar="false as variable">
<span>{{variable | json}}</span>
</div>
要么
<div *ngVar="false; let variable">
<span>{{variable | json}}</span>
</div>
要么
<div *ngVar="45 as variable">
<span>{{variable | json}}</span>
</div>
要么
<div *ngVar="{ x: 4 } as variable">
<span>{{variable | json}}</span>
</div>
也可以看看
角v4
1)div
+ ngIf
+let
<div *ngIf="{ a: 1, b: 2 }; let variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
</div>
2)div
+ ngIf
+as
视图
<div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</div>
component.ts
export class AppComponent {
x = 5;
}
3)如果您不想创建包装器div
,可以使用ng-container
视图
<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
真实性
{}
将评估为真实,因此该解决方案非常可靠。
*ngIf="{ expanded: false } as scope"
然后,如果您正在使用引导程序,则可以使用[ngClass]="{ 'in': scope.expanded }"
而(click)="scope.expanded = !scope.expanded"
不是向js
/ ts
文件中添加任何内容。
*ngIf
而不是自定义的ngvar东西):github.com/angular/angular/issues/14985
丑陋,但是:
<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>
*ngFor="let a of [(someStream$ | async).someA]
。我想与<ng-container>
它一起使用可以很好地完成工作!
*ngFor
,请注意,如果变量值更改,将重新创建所有嵌套的内容,直到您指定一个trackBy
对所有值返回相同ID 的函数为止。
您可以使用template
Angular 2或ng-template
Angular 4+中的元素在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>
-->
您可以通过使用$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
公共财产在哪里<template>
在Angular 2中使用。可以使用<template>
或<ng-template>
在Angular 4中使用,但只能使用<ng-template>
。Angular 5放弃了对的支持<template>
。
t
用
#t
是存储的模板变量ng-template
。它用于[ngTemplateOutlet]="t"
制作ng-template引用本身。
更新3
问题2451在Angular 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
输入的值。component.ts
文件中计算/准备变量可能是更好的做法。但是由于我正在整个应用程序中实施的同步方案,在某些情况下,将它们显示在视图中对我来说要容易得多。当不同的变量指向同一对象时,我会利用javascript参考规则。
There is no directive with "exportAs" set to "var"
。谁能告诉我我犯了什么错误?我已经使用了上面的指令。
declarations: [...]
的@NgModule()
。如果这不是问题,请创建一个新问题并提供可以诊断问题的代码。
这是我写的指令,它扩展了exportAs装饰器参数的用法,并允许您将字典用作局部变量。
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可以是任何有效的局部变量名称。
[key: string]: any;
到Class
来解决这个问题。
我建议这样做: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>
"?"
因为这样的消息是“未定义标识符'value'” =>“ open?.value”,但是它可以正常工作!
我使用的是角度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>
我喜欢创建指令来执行此操作的方法(调用@yurzui好)。
我最终找到了一个中型文章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
}
}
我的主要更改是:
appLet: T
为appLet: T | null
不知道为什么Angular团队不仅制定了正式的ngLet指令,还制定了什么。
原始源代码归功于@AustinMatherne
简短答案,对某人有帮助
show(lastName: HTMLInputElement){
this.fullName = this.nameInputRef.nativeElement.value + ' ' + lastName.value;
this.ctx.fullName = this.fullName;
}
*但是,您可以使用ViewChild装饰器在组件内部对其进行引用。
import {ViewChild, ElementRef} from '@angular/core';
在组件内部引用firstNameInput变量
@ViewChild('firstNameInput') nameInputRef: ElementRef;
之后,可以在组件内部的任何位置使用this.nameInputRef。
使用ng-template
就ng-template而言,它有点不同,因为每个模板都有自己的输入变量集。
https://stackblitz.com/edit/angular-2-template-reference-variable
对于那些决定使用结构化指令代替的人*ngIf
,请记住,默认情况下不对指令上下文进行类型检查。要创建类型安全的指令ngTemplateContextGuard
属性,请参阅键入指令的上下文。例如:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
// don't use 'ng' prefix since it's reserved for Angular
selector: '[appVar]',
})
export class VarDirective<T = unknown> {
// https://angular.io/guide/structural-directives#typing-the-directives-context
static ngTemplateContextGuard<T>(dir: VarDirective<T>, ctx: any): ctx is Context<T> {
return true;
}
private context?: Context<T>;
constructor(
private vcRef: ViewContainerRef,
private templateRef: TemplateRef<Context<T>>
) {}
@Input()
set appVar(value: T) {
if (this.context) {
this.context.appVar = value;
} else {
this.context = { appVar: value };
this.vcRef.createEmbeddedView(this.templateRef, this.context);
}
}
}
interface Context<T> {
appVar: T;
}
该指令可以像一样使用*ngIf
,除了它可以存储假值:
<ng-container *appVar="false as value">{{value}}</ng-container>
<!-- error: User doesn't have `nam` property-->
<ng-container *appVar="user as user">{{user.nam}}</ng-container>
<ng-container *appVar="user$ | async as user">{{user.name}}</ng-container>
与之相比,唯一的缺点*ngIf
是Angular Language Service无法确定变量类型,因此模板中没有代码完成。我希望它将尽快修复。