首页 > 解决方案 > is there an Angular event like ngDoneCheck?

问题描述

Problem

I want any way to know that angular has finished rendering *ngFor directives (EDIT:) when a new element is added to the array it is tracking dynamically, and after ngAfterViewInit.

Example

an example of my problem: I have an array of 2 things. They are generated into content editable p tags with ngFor.

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
    <p 
      *ngFor="let el of myArray" 
       contenteditable="true"
       (keydown.enter)="addNewP()"
    >{{el}}</p>
`,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  myArray = ["first", "second"];
  addNewP(){
    this.myArray.splice(1, 0, "in the middle");
  }
}

How can I get an async notification that angular is done rendering so that I can put focus on the "in the middle" element, after the user presses enter?

My current solution

Currently I'm using a custom directive from https://www.codementor.io/yomateo/auto-focus-with-angular-7-the-directive-osfcl7rrv:

import { Directive, ElementRef, AfterContentInit } from '@angular/core';

@Directive({
  selector: '[appFocusNew]'
})
export class FocusNewDirective implements AfterContentInit{

  constructor(private el: ElementRef//tiny side note: angular warns extensively against this, should i avoid it?
    ) { }

  public ngAfterContentInit() {
    setTimeout(() => {
      this.el.nativeElement.focus();
    },0)
  }
}

标签: angular

解决方案


You could use OnInit lifecycle hook in your directive. Also make sure to use the directive in the template like this appFocusNew = "". Otherwise ngOnInit may not be fired.

Directive:

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({
  selector: '[appFocusNew]'
})
export class FocusNewDirective implements OnInit {

  constructor(private el: ElementRef) { }

  ngOnInit() {
    this.el.nativeElement.focus();
  }

}

Template:

<p 
  *ngFor="let el of myArray" 
    contenteditable="true"
    (keydown.enter)="addNewP()"
    appFocusNew = ""> 
    {{el}}
</p> 

Working DEMO here.


推荐阅读