如何在使用* ngIf显示元素后获取元素?

时间:2018-02-14 12:55:42

标签: angular angular-ng-if

我经常遇到这个问题。我有一个如图所示的元素

<div class="element-1" *ngIf="isShown"></div>

默认情况下,isShown = false;

点击元素后,我正在制作isShown = true;

现在,在相同的点击回调函数中如果我尝试将element-1作为

$('.element-1'),我没有得到那个元素,因为在isShown = true时它可能不会立即出现在DOM中。

我可以使用ngAfterContentChecked获得相同的效果。但ngAfterContentChecked多次打电话。

那么,如何通过不使用ngAfterContentChecked来获取元素?

修改

这是我的元素

    <app-card-kpi-inline-overlay #kpisOverlay class="child-component all-kpis-overlay-wrap {{selectedView}}" [style.left.px]="kpiLeft" *ngIf="data['openKpiDetails']==true" [cardData]="data"></app-card-kpi-inline-overlay>

这是我的方法代码

@ViewChild('kpisOverlay') kpisOverlay: ElementRef;

showKpiSection(i, event, card) {
    card['openKpiDetails'] = !card['openKpiDetails'];
    event.stopPropagation();
    if (card['openKpiDetails']) {
        setTimeout(() => { 
            const el: HTMLElement = this.kpisOverlay.nativeElement; 
            console.log(el); // always showing undefined
        }, 0);
    }
}

我正试图切换旗帜。但控制台始终打印undefined

下面是我的切换元素

<div (click)="showKpiSection(i, $event, data)">Get element</div>

3 个答案:

答案 0 :(得分:4)

我永远不会这么说:

  

在Angular中使用JQuery是一种反模式。你不应该自己触摸DOM,你应该让框架为你做

现在,以一种完整的规范方式:

<div #firstElement *ngIf="isShown"></div>

在你的TS中:

@ViewChild('firstElement') firstElement: ElementRef;

如果你想在你的函数中使用该元素,一旦isShown的值设置为true,就使用此

const el: HTMLElement = this.firstElement.nativeElement;

如果它不起作用,则触发更改检测,因为这意味着Angular尚未检测到更改。

编辑由于您的组件处于循环中,因此您应该使用@ViewChildren

我为你做了一个工作 StackBlitz ,看看代码,它基本上是相同的原则,只是元素成为一个元素数组。

答案 1 :(得分:1)

你应该像这样定义你的元素:

<div #element-1 class="element-1" *ngIf="isShown"></div>

然后使用

访问它
@ViewChild('element-1') element1;
在您的组件中

。 此页面上的示例与您尝试执行的操作非常接近: https://angular.io/api/core/ViewChild

答案 2 :(得分:1)

您可以利用 @ViewChild@ViewChildren 行为:

<块引用>

配置视图查询的属性装饰器。变化检测器 查找第一个元素或与选择器匹配的指令 视图 DOM。如果视图 DOM 发生变化,并且新的孩子匹配 选择器,属性被更新。

1.使用 setter

的 ViewChild 方法

重要的部分是如果视图 DOM 发生变化,这意味着在这种情况下,这只会在元素被创建或销毁时触发。

首先为元素声明一个变量名,对于我使用的样本#element1

<div #element1 class="element-1" *ngIf="isShown"></div>

然后在您的组件中添加一个 @ViewChild 引用:

@ViewChild('element1') set element1(element) {
  if (element) {
     // here you get access only when element is rendered (or destroyed)
  }
}

2.使用 Observables 的 ViewChildren 方法

另一种解决方案是订阅 @ViewChildren 更改 observable,而不是使用 @ViewChild 像这样:

@ViewChildren('element1')
private element1: QueryList<any>;

然后订阅它改变可观察:

element1.changes.subscribe((d: QueryList<any>) => {
  if (d.length) {
    // here you get access only when element is rendered
  }
});

我更喜欢最后一种方式,因为对我来说,在 setter's 中处理 observable 比验证更容易,而且这种方法更接近“事件”概念。