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

+3


source to share


2 answers


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

https://alexzuza.github.io/enjoy-ng-parser

+2


source


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.

0


source







All Articles