Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect async change to ng-content

Tags:

angular

I made a component which uses the marked package to render markdown content, the thing is it doesn't re-render itself when an async event changes its ng-content element.

Here's the code

import {Component, ElementRef, AfterContentInit} from 'angular2/core';
declare var marked: any;

@Component({
    selector: 'markdown',
    template:
    '<div style="display:none;">' +
    '    <ng-content></ng-content>' +
    '</div>' +
    '<div class="markdown" [innerHTML]="output"></div>'
})
export class MarkdownComponent implements AfterContentInit {
    output: string;

    constructor(
        private element: ElementRef) {
    }

    ngAfterContentInit() {
        const c = this.element.nativeElement.childNodes;
        this.output = marked(c[0].textContent);
    }
}

Here's the HTML snippet:

<markdown>{{info}}</markdown>

And here's the async update:

updateInfo(text: string) {
    this.svc.update(this.info, text).subscribe(
        data => this.info = data.newText);
}

The problem is, when the this.svc.update event fires, the info variable changes value, but the markdown component doesn't get re-rendered.

Thanks!

RESOLUTION

Following the accepted answer's advice (thanks Gunter), here's the new component, it's leaner and simpler:

import {Component} from 'angular2/core';
declare var marked: any;

@Component({
    selector: 'markdown',
    template: '<div class="markdown" [innerHTML]="process(md)"></div>',
    inputs: ['md']
})
export class MarkdownComponent {
    md: string;

    process(s: string) {
        if (!s) return '';
        return marked(s);
    }
}

And here's the new HTML:

<markdown [md]="info"></markdown>

Works perfectly! :)

like image 322
Aviad P. Avatar asked Feb 01 '16 18:02

Aviad P.


1 Answers

Adding an @Input() content; and using the component like

<markdown [content]="info"></markdown>

would make this easier.

Alternatively a MutationObserver should work well for this specific use case.

like image 127
Günter Zöchbauer Avatar answered Oct 13 '22 18:10

Günter Zöchbauer