【问题标题】:Angular 2/4/5/6 - Transforming the innerHTML of a custom component on its component class sideAngular 2/4/5/6 - 在其组件类端转换自定义组件的 innerHTML
【发布时间】:2019-01-13 15:54:39
【问题描述】:

我想制作以下基本组件:card.component 将用户在其 innerHTML 上定义的任何内容放入其组件类中,以便对其进行转换并在其模板上显示。

这是用户将如何使用此组件的方式:

<app-card>hello world, this is a sample text</app-card>

在这里,您有一个位于 StackBlitz.com 的基础项目,您可以对其进行 fork 以使其工作。

https://stackblitz.com/edit/angular-cmdpgh?file=src%2Fapp%2Fcomponents%2Fcard%2Fcard.component.ts

这里有代码预览:

import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-card',
    templateUrl: 'card.component.html',
    styleUrls: [ 'card.component.css' ],
})
export class CardComponent implements OnInit {

  private content: string;

  ngOnInit() {
    // please, override this to get the real innerHTML on: 'app.component.html'
    let innerHTML = 'testing';
    this.content = CardComponent.complexStrTransform(innerHTML);
  }
  private static complexStrTransform(str: string): string {
    // complex transformations here
    let result = '';
    for (let i = 0; i < str.length; i++) {
      let c = str[i];
      result += c;
      result += c.toUpperCase();
      result += '|';
    }
    result = '!!!' + result + '!!!';
    return result;
  }
}
<mat-card>
    <mat-card-content>
        {{content}}
    </mat-card-content>
    <mat-card-actions>
        <button mat-button>LIKE</button>
        <button mat-button>SHARE</button>
    </mat-card-actions>
</mat-card>

{{content}} 的位置上,组件应显示以下结果:complexStrTransform(...)

我在一些可以使用的地方看到:&lt;ng-content&gt;&lt;/ng-content&gt; 在组件的模板上指定要放置 innerHTML 的位置,但我认为这不是最好的选择,因为我需要转换 @ 987654332@ 具有非常复杂的更改,只能在组件类上完成。

有什么建议吗?

感谢您的关注。

【问题讨论】:

    标签: javascript angular typescript angular-material material-design


    【解决方案1】:

    我不确定这是否正是您所需要的,但我尝试编写一个小解决方案来与您的示例进行一般组件交互,

    1. 在您的卡片组件中,

    添加一个我们稍后可以从主应用程序组件中使用的输入,

     @Input('complexInput') complexInputContent: string;
    

    然后对添加的全局输入初始化innerHTML,

     let innerHTML = this.complexInputContent;
    
    1. 如下更新您的应用组件,

    <app-card  [complexInput]="contentDiv.innerText">
    
    
    <div #contentDiv contenteditable="true" >
    
    hello world, this is a sample text
    
    </div>
    
    
    </app-card>

    这是有效的解决方案(预览版):https://angular-k5wjbp.stackblitz.io/

    可编辑代码:https://stackblitz.com/edit/angular-k5wjbp

    参考:https://angular.io/guide/component-interaction

    【讨论】:

    • 这是一个很好的尝试,但我正在寻找更简单的东西,例如:&lt;app-card&gt;hello world, this is a sample text&lt;/app-card&gt;
    【解决方案2】:

    Dilusha 之前的回答完成了部分工作。另一部分是将您的转换功能实现为管道,并使用一些 DOM 技巧。 Here is is on Stackblitz.

    首先,将您的转换函数重新设计为管道(并重构组件):

    import { Component, Pipe, PipeTransform } from '@angular/core';
    
    @Component({
      selector: 'app-card',
      templateUrl: 'card.component.html',
      styleUrls: ['card.component.css'],
    })
    export class CardComponent { }
    
    @Pipe({ name: 'complexStr' })
    export class ComplexStrPipe implements PipeTransform {
      transform(str: string): string {
        // complex transformations here
        let result = '';
        for (let i = 0; i < str.length; i++) {
          let c = str[i];
          result += c;
          result += c.toUpperCase();
          result += '|';
        }
        result = '!!!' + result + '!!!';
        return result;
      }
    }
    

    接下来,将ng-content 标签添加到您的组件中,以便用户可以简单地插入内容。同时,使用display: none 隐藏它并为其分配一个模板引用变量,以便您的组件可以访问它并使用管道显示它:

    <mat-card>
        <mat-card-content>
            {{inner.innerText | complexStr}}
        </mat-card-content>
        <mat-card-actions>
            <button mat-button>LIKE</button>
            <button mat-button>SHARE</button>
        </mat-card-actions>
    </mat-card>
    <div #inner style="display: none">
        <ng-content></ng-content>
    </div>
    

    现在您的组件可以正常工作了:

    <app-card>hello world, this is a sample text</app-card>
    

    这显然是一种 hack,因为原始用户内容仍然存在于 DOM 中。但它可以非常有效地完成工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-23
      • 2018-04-17
      • 2018-11-15
      • 2016-05-06
      • 2019-06-13
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多