【问题标题】:Render Angular component via Wordpress REST API通过 Wordpress REST API 渲染 Angular 组件
【发布时间】:2018-09-09 13:26:20
【问题描述】:

我有一个 Angular 5 应用程序,它通过 REST API 使用来自 Wordpress 的内容。

我想做的是在 Wordpress 内容编辑器中插入一个组件标签,然后让它出现在应用程序中。

比如我创建了一个简单的组件<app-some-component></app-some-component>

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

@Component({
  selector: 'app-some-component',
  template: `
  <h1>I am a component!</h1>
  `
})
export class SomeComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}

并直接添加到宿主组件模板中进行测试,就可以了。

现在,该主机组件还通过其余 API 从 Wordpress 中提取内容。所以我尝试在 Wordpress 内容编辑器中添加&lt;app-some-component&gt;&lt;/app-some-component&gt;

标签“通过”到 Angular 应用程序,我在检查页面时看到 HTML 中的标签。但是组件的内容没有渲染,所以我猜它没有被Angular处理。

我正在使用安全管道来允许组件中包含 HTML,如

        <div class="card"
           *ngFor="let vid of videolist">
        <img class="card-img-top img-fluid"
             [src]="vid.better_featured_image.source_url"
             alt="Video Thumbnail">
        <div class="card-body">
          <h4 class="card-title"
              [innerHTML]="vid.title.rendered"></h4>
          <p class="card-text"
             [innerHTML]="vid.content.rendered | safe: 'html'"></p>
        </div>
        <div class="card-footer">
          <a routerLink="/videos/{{vid.id}}">View Video</a>
        </div>
      </div>

管道的代码是

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';

@Pipe({ name: 'safe' })

// see https://medium.com/@swarnakishore/angular-safe-pipe-implementation-to-bypass-domsanitizer-stripping-out-content-c1bf0f1cc36b
// usage: <div [innerHtml]="htmlSnippet | safe: 'html'"></div>
export class SafePipe implements PipeTransform {
  constructor(protected sanitizer: DomSanitizer) {}

  public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
      case 'html':
        return this.sanitizer.bypassSecurityTrustHtml(value);
      case 'style':
        return this.sanitizer.bypassSecurityTrustStyle(value);
      case 'script':
        return this.sanitizer.bypassSecurityTrustScript(value);
      case 'url':
        return this.sanitizer.bypassSecurityTrustUrl(value);
      case 'resourceUrl':
        return this.sanitizer.bypassSecurityTrustResourceUrl(value);

      default:
        throw new Error(`Invalid safe type specified: ${type}`);
    }
  }
}

我需要做什么才能让组件呈现?

【问题讨论】:

    标签: javascript wordpress angular wordpress-rest-api angular-pipe


    【解决方案1】:

    这只是将纯 html 写入 dom,您需要 Angular 将其实际呈现为组件。为此,您有一些选择:

    你可以用很多*ngIf*ngSwitch指令编写一个组件:

    import { Component, Input } from '@angular/core'
    
    @Component({
      selector: 'app-blog-post',
      template: `
        <article>
          <ng-container *ngFor="let data of datas">
            <app-component-1 [data]="data" *ngIf="data.type === '1'"></app-component-1>
            <app-component-2 [data]="data" *ngIf="data.type === '2'"></app-component-2>
            <app-component-3 [data]="data" *ngIf="data.type === '3'"></app-component-3>
          </ng-container>
        </article>
      `,
      styleUrls: ['./blog-post.component.scss'],
    })
    export class BlogPostComponent {
      @Input() datas: any[]
    }
    

    您可以使用Angular Dynamic Component Loader 以编程方式呈现组件:

    import {
      Component,
      ComponentFactoryResolver,
      Input,
      OnInit,
      ViewChild,
      ViewContainerRef,
    } from '@angular/core'
    import { Component1 } from '../component-1/component-1.component'
    import { Component2 } from '../component-2/component-2.component'
    import { Component3 } from '../component-3/component-3.component'
    
    @Component({
      selector: 'app-blog-post',
      template: `
        <article>
          <app-blog-post-micro-component *ngFor="let data of datas" [data]="data"></app-blog-post-micro-component>
        </article>
      `,
    })
    export class BlogPostComponent {
      @Input() datas: any[]
    }
    
    
    @Component({
      selector: 'app-blog-post-micro-component',
      template: '<ng-container #container></ng-container>',
    })
    export class BlogPostMicroComponent implements OnInit {
      @Input() data: any[]
      @ViewChild('container', { read: ViewContainerRef }) private container: ViewContainerRef
    
      constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
    
      ngOnInit() {
        // Prepare to render the right component
        const component = this.getComponentByType(this.data.type)
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component)
    
        // Clear the view before rendering the component
        const viewContainerRef = this.container
        viewContainerRef.clear()
    
        // Create component
        const componentRef = viewContainerRef.createComponent(componentFactory)
        componentRef.instance.data = this.data
      }
    
      private getComponentByType(type: string) {
        const componentMapByType = { '1': Component1, '2': Component2, '3': Component3 }
        return componentMapByType[type]
      }
    }
    

    您应该阅读这篇文章以了解更多信息:Angular Dynamic Components

    【讨论】:

    • 我不确定这将如何让 wordpress 中的 HTML 中指定的组件在我的应用程序中呈现。我们在 Angular 应用程序中使用了几个组件。我正在尝试找到一种方法,让我在 wordpress 中的内容人员可以像在实际应用程序代码中一样删除组件标签。
    • 我明白了,但我认为你现在还不能按照自己的方式去做。我也尝试过这样做,但没有找到任何关于如何做到这一点的文档。
    • 我在其他地方使用过这些,但我不明白这将如何使 Angular 识别和呈现组件 HTML,该组件 HTML 在 Wordpress 的innerHTML 绑定中发送。
    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 2020-12-23
    • 2019-06-20
    • 2020-09-19
    • 1970-01-01
    相关资源
    最近更新 更多