简体   繁体   中英

How to execute a function, when angular ngFor creates an element in the DOM?

I have a server side script, that saves sensor information to the database. This information then should be displayed on the front-end. The front-end is an angular app. The sensor information from the database would be displayed in graphs that is based on the smoothie package. On the front-end during the page load I call an API end point in the ngOnInit function and that returns with an output like this:

[
    {
        "id": 1,
        "name": "CPU Usage",
        "frequency": 5,
        "unit": "%"
    },
    {
        "id": 2,
        "name": "Memory Usage",
        "frequency": 4,
        "unit": "GB"
    }
]

Then I load this to an array:

  public charts: Chart[] = [];

  constructor(private httpClient: HttpClient, private dataService: ApiService) { }

  ngOnInit(): void {
    this.httpClient.get<any>(this.dataService.baseUrl + '/measurable/active').subscribe({
      next: data => {
        for (let i = 0; i < data.length; i++) {
          let smoothie = new SmoothieChart();

          this.charts.push(new Chart(data[i].id, data[i].name, data[i].unit, smoothie));
        }

        console.debug(this.charts);
      },
      error: error => {
        console.error('Could not load any measurable', error.message);
      }
    })
  }

And display some necessary canvas' for the smoothie in the html with the help of the ngFor:

<div class="container">
  <div class="row">
    <div class="col-md-6 mx-auto">
      <p>dashboard works!</p>
      <div class="row" *ngFor="let chart of charts">
        <label>{{ chart.name }}({{ chart.unit }})</label>
        <canvas id="{{ chart.id }}" style="width:100%; height:200px" width="1262" height="200"></canvas>
      </div>
    </div>
  </div>
</div>

During this loading process I would like to call a function upon each element after I displayed the canvas, that will initialize the smoothie graph for streaming the data. I can not use the ngAfterViewinit function, because the API call is asynchronous and it is executed before the request returns with the data. I read it in some similar posts that I can create a directive to do this, however most likely due to the lack of knowledge in angular I couldn't not understand and reproduce it(meaning: I got the idea behind it also copied all the codes, but none worked)

Can someone show me how to solve this issue and explain the logic behind it so someone as inexperienced in angular like myself can understand it too?

create a directive in angular like:-

@Directive({
  selector: '[refresh]'
})
export class RefreshDirective implements OnInit {
  @Output() init = new EventEmitter();
  ngOnInit() {
     this.init.emit()
  }
}

And Change your html to:-

<div class="container">
  <div class="row">
    <div class="col-md-6 mx-auto">
      <p>dashboard works!</p>
      <div class="row" *ngFor="let chart of charts">
        <label>{{ chart.name }}({{ chart.unit }})</label>
        <canvas id="{{ chart.id }}" style="width:100%; height:200px" width="1262" height="200" refresh (init) = "myMethod()"></canvas>
      </div>
    </div>
  </div>
</div>

where change myMethod to function name you want to call and also don't forget to import this directive in declaration array of your module.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM