访问 *ngIf 中的局部变量
access local variable within *ngIf
我有一个带下拉菜单的 primeng (angular 2) 对话框。我想在对话框显示时将焦点设置到下拉列表。问题似乎是我的 div
是有条件地呈现的。
我的代码:
<p-dialog (onShow)="fe.applyFocus()">
<div *ngIf="selectedItem">
<button pButton type="button" (click)="fe.applyFocus()" label="Focus"></button>
<p-dropdown #fe id="reason" [options]="reasonSelects" [(ngModel)]="selectedReason" ></p-dropdown>
</div>
</p-dialog>
在此代码中,按钮工作正常,但 onShow()(在 *ngIf
div 之外)告诉我 fe
未定义。
如何访问 *ngIf
中的局部变量?
是的,这是一个真正的痛苦。不幸的是,由于 *ngIf 的工作方式,它完全封装了内部的所有内容(包括它所在的标签)。
这意味着在带有 ngIf 的标签上或标签内声明的任何内容都不会 "visible" 在 ngIf 之外。
而且您甚至不能简单地将 @ViewChild 放在 ts 中,因为一开始 运行 它可能不存在...所以这个问题有 2 个已知的解决方案...
a) 你可以使用@ViewChildren。这将为您提供一个您可以订阅的 QueryList,它会在每次 tempalte 变量更改时触发(即 ngIf 打开或关闭)。
(html 模板)
<div>{{thing.stuff}}</div>
<my-component #thing></my-component>
(ts 代码)
@ViewChildren('thing') thingQ: QueryList<MyComponent>;
thing: MyComponent;
ngAfterViewInit() {
this.doChanges();
this.thingQ.changes.subscribe(() => { this.doChanges(); });
}
doChanges() {
this.thing = this.thingQ.first;
}
b) 您可以将@ViewChild 与setter 一起使用。这将在每次 ngIf 更改时触发 setter。
(html 模板)
<div>{{thing.stuff}}</div>
<my-component #thing></my-component>
(ts 代码)
@ViewChild('thing') set SetThing(e: MyComponent) {
this.thing = e;
}
thing: MyComponent;
这两个示例都应该为您提供一个 "thing" 变量,您现在可以在 ngIf 之外的模板中使用它。您可能希望为 ts 变量指定一个与模板 (#) 变量不同的名称,以防发生冲突。
你可以在NgIf层面单独使用template:
<ng-container *ngIf="selectedItem; else elseTemplate">
<p-dialog (onShow)="fe.applyFocus()">
<div>
<button pButton type="button" (click)="fe.applyFocus()" label="Focus"></button>
<p-dropdown #fe id="reason" [options]="reasonSelects" [(ngModel)]="selectedReason"></p-dropdown>
</div>
</p-dialog>
</ng-container>
<ng-template #elseTemplate>
<p-dialog>
</p-dialog>
</ng-template>
我有一个带下拉菜单的 primeng (angular 2) 对话框。我想在对话框显示时将焦点设置到下拉列表。问题似乎是我的 div
是有条件地呈现的。
我的代码:
<p-dialog (onShow)="fe.applyFocus()">
<div *ngIf="selectedItem">
<button pButton type="button" (click)="fe.applyFocus()" label="Focus"></button>
<p-dropdown #fe id="reason" [options]="reasonSelects" [(ngModel)]="selectedReason" ></p-dropdown>
</div>
</p-dialog>
在此代码中,按钮工作正常,但 onShow()(在 *ngIf
div 之外)告诉我 fe
未定义。
如何访问 *ngIf
中的局部变量?
是的,这是一个真正的痛苦。不幸的是,由于 *ngIf 的工作方式,它完全封装了内部的所有内容(包括它所在的标签)。
这意味着在带有 ngIf 的标签上或标签内声明的任何内容都不会 "visible" 在 ngIf 之外。
而且您甚至不能简单地将 @ViewChild 放在 ts 中,因为一开始 运行 它可能不存在...所以这个问题有 2 个已知的解决方案...
a) 你可以使用@ViewChildren。这将为您提供一个您可以订阅的 QueryList,它会在每次 tempalte 变量更改时触发(即 ngIf 打开或关闭)。
(html 模板)
<div>{{thing.stuff}}</div>
<my-component #thing></my-component>
(ts 代码)
@ViewChildren('thing') thingQ: QueryList<MyComponent>;
thing: MyComponent;
ngAfterViewInit() {
this.doChanges();
this.thingQ.changes.subscribe(() => { this.doChanges(); });
}
doChanges() {
this.thing = this.thingQ.first;
}
b) 您可以将@ViewChild 与setter 一起使用。这将在每次 ngIf 更改时触发 setter。
(html 模板)
<div>{{thing.stuff}}</div>
<my-component #thing></my-component>
(ts 代码)
@ViewChild('thing') set SetThing(e: MyComponent) {
this.thing = e;
}
thing: MyComponent;
这两个示例都应该为您提供一个 "thing" 变量,您现在可以在 ngIf 之外的模板中使用它。您可能希望为 ts 变量指定一个与模板 (#) 变量不同的名称,以防发生冲突。
你可以在NgIf层面单独使用template:
<ng-container *ngIf="selectedItem; else elseTemplate">
<p-dialog (onShow)="fe.applyFocus()">
<div>
<button pButton type="button" (click)="fe.applyFocus()" label="Focus"></button>
<p-dropdown #fe id="reason" [options]="reasonSelects" [(ngModel)]="selectedReason"></p-dropdown>
</div>
</p-dialog>
</ng-container>
<ng-template #elseTemplate>
<p-dialog>
</p-dialog>
</ng-template>