简体   繁体   中英

Angular2 ngFor elements with Material Design Lite

I'm struggling to make Material Design Lite component to work with dynamically added elements via *ngFor. I understand that I need to call componentHandler.upgradeElement, but where do I put this call? I was trying this and this directives but they don't seem to work. Specifically, I need mdl-menu on each item of my array. Any suggestions on where to look at?

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();
        });
     }
}

Problem: MDL does not watch dynamically created DOM element.

Solution: MDL library adds componentHandler property onto Window object. execute the below code inside ngOnInit() method of the component in which you are adding element dynamically.

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

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