Angular2 ngFor Elements with Material Design Lite

I'm struggling to get Material Design Lite to work with dynamically added elements through * ngFor. I understand that I need to call componentHandler.upgradeElement, but where can I put this call? I tried this and this directives, but they don't seem to work. In particular, I need an mdl menu for each element of my array. Any suggestions on what to look at?

+6
source share
2 answers

TL; DR; You need to call the componentHandler.upgradeElement component after the elements have been entered into the DOM. The approach I used in the past is described in the example below.

EDIT If you want a declarative solution, this approach would look pretty good here, but I didn't use it myself.

I created a service that wraps a Material LiteHandler component

import { Injectable } from '@angular/core'; export interface ComponentHandler { upgradeDom(); } declare var componentHandler: ComponentHandler; @Injectable() export class MaterialService { handler: ComponentHandler; constructor() { this.handler = componentHandler; } // render on next tick render() { setTimeout(() => { this.handler.upgradeDom(); }, 0); } } 

Then you call the service rendering function after the component has injected these elements into the DOM. In your case, this happens after *ngFor

This is a very contrived example, but it demonstrates "where" to invoke rendering.

 import { Component, OnInit } from '@angular/core'; import { DataService } from 'services/data.service'; import { MaterialService } from 'services/material.service'; @Component({ selector: 'app-thing', templateUrl: ` <ul> <li *ngFor="let item of data"> {{data}} </li> </ul> ` }) export class ThingComponent implements OnInit { data: string[] constructor( private service: DataService, private material: MaterialService ) { } ngOnInit() { this.service.getData() .subscribe(data => { this.data = data; this.material.render(); }); } } 
+1
source

Problem: MDL does not track a dynamically created DOM element.

Solution: The MDL library adds the componentHandler property to the Window object. execute the code below inside the ngOnInit () method of the component into which you add the element dynamically.

 setTimeout(() => { window['componentHandler'].upgradeDom(); }, 0); 
0
source

All Articles