Angular 2/4 save ContentChild template as string
I have a component app-preview
that has a pushed component from its parent to it ng-content
.
app-preview
S 'parent code :
<app-preview>
<checkbox #prv
[indeterminate]="true"
[checked]="true">
</checkbox>
</app-preview>
I want app-preview
not only for rendering, but also for saving as a string to any template property of any component that was clicked on it ng-content
. So I want to app-preview
keep the following line:
"<checkbox #prv
[indeterminate]="true"
[checked]="true">
</checkbox>"
to its property and use the file in it .ts
. For example:this.childTmpl
How can I achieve this?
thank
source to share
I assume you are using @angular/compiler
.
So, in this case, it can be easily done by overriding, for example, the method I18NHtmlParser.parse
:
import { Attribute as HtmlAttribute, I18NHtmlParser } from '@angular/compiler';
function visitAll(visitor: any, nodes: any[]): any[] {
const result: any[] = [];
nodes.forEach(ast => ast.visit(visitor));
return result;
}
class MyVisitor {
visitElement(ast: any) {
if(ast.name === 'app-preview') {
const text = ast.sourceSpan.start.file.content
.substring(ast.startSourceSpan.end.offset, ast.endSourceSpan.start.offset);
ast.attrs.push(new HtmlAttribute('childTmpl', text, ast.startSourceSpan))
}
visitAll(this, ast.children);
}
visitAttribute() {}
visitText() {}
visitComment() {}
}
const originParse = I18NHtmlParser.prototype.parse;
const visitor = new MyVisitor();
I18NHtmlParser.prototype.parse = function() {
const result = originParse.apply(this, arguments);
visitAll(visitor, result.rootNodes)
return result;
};
It will collect the text between the tag app-preview
and pass it to the attribute childTmpl
that will be converted to @Input
.
After that, you can get the ContentChild line in
app-preview.component.ts
export class AppPreview {
@Input() childTmpl: string;
ngOnInit() {
console.log(this.childTmpl);
}
}
If you want to see it in action take a look at the Plunger Example
PS Don't do this if you don't know what it does.
To see how angular parses a template take a look
source to share
Try adding a link to your app preview
<app-preview [title]="'PREVIEW'" [id]="'prev'" #test>
<checkbox #prv
[indeterminate]="true"
[checked]="true">
</checkbox>
</app-preview>
And in your .ts file, you can get the inner HTML of your native element and save it however you want:
@ViewChild('test') input:ElementRef;
ngAfterViewInit() {
console.log(this.input.nativeElement.innerHTML);
}
Don't forget to import ElementRef and ViewChild.
source to share