在模板中计算角度 *ngIf 语句时触发的事件

问题描述 投票:0回答:2

如果我有以下情况:

<div *ngIf="user$ | async as user" class="container">
   <p>{{user.name}}</p>
</div>

当上面的

div
最终出现在屏幕上时,有什么方法可以执行代码吗?

angular angular-ng-if angular-template
2个回答
33
投票

*ngIf
将删除该 DOM 元素和所有附加组件/指令。所以你可以只写一个简单的指令,在事件第一次创建时执行它。当
*ngIf
false 转换为 true 指令将被创建(一次又一次,等等......)

@Directive({selector: '[after-if]'})
export class AfterIfDirective implements AfterContentInit {
    @Output('after-if')
    public after: EventEmitter<void> = new EventEmitter<void>();

    public ngAfterContentInit(): void {
       // timeout helps prevent unexpected change errors
       setTimeout(()=> this.after.next());
    }
}

示例 HTML:

<div *ngIf="user$ | async as user" (after-if)="your expression">
   <p>{{user.name}}</p>
</div>

21
投票

不创建新指令的解决方案是利用

@ViewChild
@ViewChildren
行为:

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

1。查看孩子

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

首先为元素声明一个变量名,对于我使用的示例

#userContent

<div #userContent *ngIf="user$ | async as user" class="container">
  <p>user.name</p>
</div>

然后在您的组件中添加一个

@ViewChild
引用:

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

此解决方案在另一个问题中提供,也

@ViewChild
行为细节可用here.

2。查看孩子

另一种不使用新指令的解决方案是订阅

@ViewChildren
改变 observable,而不是使用
@ViewChild
像这样:

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

然后订阅它改变可观察的:

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

我更喜欢最后一种方式,因为对我来说,处理可观察对象比在内部进行验证更容易

setter's
,而且这种方法更接近“事件”概念。


关于 Observables 的注意事项:

所有可观察对象都需要取消订阅,否则会引起内存泄漏;有很多方法可以防止这种情况发生,作为推荐,我最喜欢的方法是 RxJs 函数

takeUntil
,这部分:
pipe(takeUntil(this.$d))
以及您的
ngOnDestroy
方法中的以下内容:

private $d = new Subject();
ngOnDestroy() {
    this.$d.next();
    this.$d.complete();
}

我推荐这种方式的原因是因为实现它的额外代码量非常低; 您可以对组件中的所有订阅 使用相同的变量 (

this.$d
)。有关取消订阅方法的更多详细信息/选项,请参阅其他相关问题/答案

© www.soinside.com 2019 - 2024. All rights reserved.