【问题标题】:access local variable within *ngIf访问 *ngIf 中的局部变量
【发布时间】:2017-10-17 03:41:00
【问题描述】:

我有一个带有下拉菜单的primeng(角度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 中的局部变量?

【问题讨论】:

  • 遇到同样的问题..

标签: angular2-template primeng


【解决方案1】:

是的,这真的很痛苦。不幸的是,由于 *ngIf 的工作方式,它完全封装了内部的所有内容(包括它所在的标签)。

这意味着在带有 ngIf 的标记上或内部声明的任何内容都不会在 ngIf 之外“可见”。

而且你甚至不能简单地将@ViewChild 放在 ts 中,因为在第一次运行时它可能不存在......所以这个问题有 2 个已知的解决方案......

a) 您可以使用@ViewChildren。这将为您提供一个您可以订阅的 QueryList,它会在每次模板变量更改时触发(即 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;

这两个例子都应该给你一个“东西”变量,你现在可以在你的模板中使用,在 ngIf 之外。您可能需要为 ts 变量指定与模板 (#) 变量不同的名称,以防发生冲突。

【讨论】:

  • 好吧,我的 ViewChildren 示例的原始版本不起作用 - 但我已经更改了它,现在它可以正常工作了 :)
  • 不错的答案。就我而言,我还必须在this.thing = e 之后执行this.cdr.detectChanges();,因为我得到了ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
  • 这很棘手且不直观,但它确实有效。我不确定如何在 ViewChild 上调用 setter 的文档在哪里,但根本不清楚。当我将设置器从 ViewChild 移开时,它从未被调用,但是当它附加到 ViewChild 时它确实可以工作。
【解决方案2】:

您可以在 NgIf 级别上分离模板的使用:

<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>

【讨论】:

  • 这很棒。我到处寻找正确的答案,但它们都很复杂。这很容易完全满足同时使用局部变量和 ngIf 的要求。谢谢!
  • 这没有意义。我们如何从 typescript 组件访问#elseTemplate 或其中的任何本地模板变量?当我尝试时,它没有直接引用它。
  • @TetraDev 问题没有提到访问打字稿中的局部变量
  • 没错,您的解决方案确实适用于所述问题。赞成:-)
猜你喜欢
  • 2016-08-07
  • 2017-12-28
  • 2020-06-29
  • 1970-01-01
  • 2019-10-04
  • 1970-01-01
  • 2011-04-19
  • 2020-07-30
相关资源
最近更新 更多