【问题标题】:Get the original / raw template value of ng-content获取 ng-content 的原始/原始模板值
【发布时间】:2021-04-15 02:58:29
【问题描述】:

是否可以得到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 的角度渲染内容,而不是原始的原始模板。

【问题讨论】:

    标签: angular ng-content


    【解决方案1】:

    这不一定回答您关于从ng-content 获取预处理 HTML 的问题。但是,此方法可用于解决有关显示 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>
    

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

    【讨论】:

    • 这很巧妙。值得注意的是,我们可以将my-component-example.component.html 放入一个常量字符串中。
    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 2014-05-31
    • 2012-05-28
    • 1970-01-01
    • 2021-12-16
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多