Angular2 ngFor elements with Material Design Lite
TLDR; You need to call componentHandler.upgradeElement after the elements have been injected into the DOM. An approach I've used in the past is described in the example below.
EDIT If you want a declarative solution this approach here seem like a pretty good one, but I have not used it myself.
I created a service that wraps the Material Lite componentHandler
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's render function after the component has injected the elements into the DOM. In your case this is after the *ngFor
This is a very contrived example but demonstrates "where" to call render
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();
});
}
}