我创建了一个使用marked
包来呈现markdown内容的组件,当异步事件更改其ng-content
元素时,它不会重新呈现。
这是代码
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);
}
}
以下是HTML代码段:
<markdown>{{info}}</markdown>
这是异步更新:
updateInfo(text: string) {
this.svc.update(this.info, text).subscribe(
data => this.info = data.newText);
}
问题是,当this.svc.update
事件触发时,info
变量会更改值,但markdown
组件不会重新呈现。
谢谢!
解决
按照接受的答案的建议(感谢Gunter),这是新组件,它更精简,更简单:
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);
}
}
这是新的HTML:
<markdown [md]="info"></markdown>
完美的作品! :)
答案 0 :(得分:3)
答案 1 :(得分:2)
即使Günter的答案很好,我也无法抗拒创建一个描述如何将Marked用于组件的小插件:https://plnkr.co/edit/0oSeaIyMWoq5fAKKlJLA?p=preview。
以下是详细信息:
标记配置HTML文件
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: { emitDecoratorMetadata: true },
packages: {
'src': {defaultExtension: 'ts'}
},
map: {
marked: 'https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.js'
}
});
System.import('src/boot')
.then(null, console.error.bind(console));
</script>
使用标记
的组件import { Component, Input } from 'angular2/core';
import marked from 'marked';
@Component({
selector: 'markdown',
template: `
<div [innerHTML]="convertedData"></div>
`
})
export class MarkdownComponent {
@Input('data')
data:string;
ngOnChanges() {
this.convertedData = marked(this.data);
}
}
使用上一个Markdown组件的组件
import { Component } from 'angular2/core';
import { MarkdownComponent } from './markdown';
@Component({
selector: 'my-app',
template: `
<div>
<markdown [data]="markdown"></markdown>
</div>
`,
directives: [ MarkdownComponent ]
})
export class AppComponent {
constructor() {
this.markdown = 'Hello';
setTimeout(() => {
this.markdown = `
# Title
Some __test__
`;
}, 1000);
}
}