1

是否有可能获得 的预处理值ng-content?我正在构建设计系统文档并希望在不重复自己的情况下显示示例代码

html

<tr>
  <td #contentEl>
    <ng-content #projected></ng-content>
  </td>
  <td>
    <mat-icon (click)="copyTagToClipboard()">content_paste</mat-icon>
  </td>
  <td>
    <pre>{{ contentEl.innerHTML }}</pre>
  </td>
</tr>

打字稿

export class CodeExampleComponent implements OnInit, AfterContentInit {
  @ViewChild('contentEl') contentEl: HTMLTableCellElement;
  @ContentChild('template') template;
  @ViewChild('projected', { read: TemplateRef, static: true }) content;

  constructor() {}

  ngOnInit() {
    console.log(this.content);
  }

  ngAfterContentInit(): void {
    console.log(this.template);
  }
  
  copyTagToClipboard() {
    if (!this.contentEl) return;
    copyToClipboard(this.contentEl.innerHTML);
  }
}

用法

  <app-code-example>
    <template #template><app-footnote>Footnote</app-footnote></template>
  </app-code-example>

我所能得到的只是 ng-content/template 的角度渲染内容,而不是原始的原始模板。

4

1 回答 1

2

这不一定回答您关于从ng-content. 但是,此方法可用于解决有关显示 HTML 作为示例的问题。您可以将原始 html 作为字符串导入并将其用作变量。然后,我喜欢创建一个或多个组件来演示我正在记录的某些组件的用法。

这有点多,所以我把它全部放在StackBlitz中来尝试和演示。

src在名为的目录中创建一个文件typings.d.ts,允许我们将 html 文件作为文本导入。

declare module "*.html" {
  const content: string;
  export default content;
}

创建一个我们所有示例组件都需要实现的抽象类。我们需要它是抽象的,因为我们QueryList稍后会用到。

export abstract class Example {
  templateText: string; //the raw html to display 
}

创建一个示例包装器组件,该组件显示实时示例、原始 html 并具有您的复制按钮

import { Component, ContentChildren, Input, QueryList } from "@angular/core";
import { Example } from "../example";

@Component({
  selector: "app-example",
  template: `
    <div class="wrapper">
        <h1>{{label}}</h1>
        <ng-content></ng-content>
    
        <br />
        <button (click)="copyTagToClipboard()">Copy Content</button>
    
        <div>
            <pre>{{ example.templateText }}</pre>
        </div>
    </div>
  `
})
export class ExampleComponent{
  @Input() label: string; 
  
  @ContentChildren(Example) items: QueryList<Example>;
  example: Example;

  ngAfterContentInit(): void {
    //grab the first thing that implements the "Example" interface
    //hypothetically this component could be re-worked to display multiple examples!
    this.example = this.items.toArray()[0];    
  }

  copyTagToClipboard() {
    alert(this.example.templateText);
  }
}

构建一个组件来演示如何使用您正在记录的任何组件。注意我们如何将 html 文件作为变量导入,并将其用作组件的属性,以满足接口。不要忘记设置提供程序,以便QueryList获取组件。然后,您可以根据需要构建尽可能多的这些示例,也许每个用例都可以构建不同的组件。

import { Component, TemplateRef, ViewChild } from "@angular/core";
import { Example } from "../example";

// See typings.d.ts, which sets up the module that allows us to do this
import * as template from "./my-component-example.component.html";
// or const template = `<app-my-component [label]="myLabelValue"></app-my-component>`;

@Component({
  selector: "app-my-component-example",
  template,
  styleUrls: ["./my-component-example.component.css"],

  //this is so the QueryList works in the example wrapper
  providers: [{ provide: Example, useExisting: MyComponentExampleComponent }]
})
export class MyComponentExampleComponent implements Example {
  myLabelValue = "Test Label!!";
  templateText = template.default;
}

最后,把它们放在一起

<app-example label="Basic Example">
  <app-my-component-example></app-my-component-example>
</app-example>

我觉得通过这种方法,您可以灵活地创建每个示例。

于 2021-01-09T19:12:06.183 回答