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! :)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With