在Angular 2中解析HTML字符串并提取和更新值

时间:2017-06-03 21:48:54

标签: angular svg

我刚刚开始研究Angular项目,但有点卡住了。我有一个组件从(可信的)外部源接收HTML字符串。我想从这个字符串中提取和更新值,并在我的组件中发送它。

现在可以使用以下代码轻松显示字符串:

<div [innerHTML]="displayString"></div>

我的输入字符串包含一些<span>元素,其中data-card-text元素作为标识符附加。是否可以提取此值,并在我的组件需要时更新它?

示例: let displayString:string = "<svg><text data-card-text>Value I want to update</text></svg>"

在Angular 2中,甚至可以进行类似的操作吗?

6 个答案:

答案 0 :(得分:8)

您必须创建一个共享服务,其中所有全局变量的定义如下所示。您的全局变量是“ displayString

export interface SharedModel {
    displayString: string;
    dynamicValue: string;
}

@Injectable()
export class Shared {
    SharedComponent: SharedModel = {
           dynamicValue:'',
           displayString: '<svg><text data-card-text>'+this.SharedComponent.dynamicValue+'</text></svg>'
    };
}

现在,您需要在组件中访问此服务,您需要设置/获取 displayString ,如下所示。

import { Shared, SharedModel } from '../Shared';
export class MyComponent {
     public sharedData: SharedModel;
     constructor(public sharedResource: Shared)
     {
         this.sharedData = sharedResource.SharedComponent;
     }
}

分配值(在您的情况下可能在其他组件/服务/ APi中)

ngOnInit()
{
     this.sharedData.dynamicValue="My name is SANDIP PATEL"
}
HTML中的

访问/获取值:

<div [innerHTML]="sharedData.displayString"></div>

答案 1 :(得分:3)

您可以使用平台浏览器模块中的DomSanitizer

import {DomSanitizer} from '@angular/platform-browser';

通过在构造函数中初始化

,在组件中注入DomSanitizer
  constructor(private domSanitizer: DomSanitizer)

使用DomSanitizer的bypassSecurityTrustHtml()并传递原始html内容:

this.displayString= this.domSanitizer.bypassSecurityTrustHtml("<svg><text data-card-text>Value I want to update</text></svg>");

我希望这能解决你的问题。

答案 2 :(得分:2)

在您的组件中,您可以将变量displayString定义为公共,然后您可以在html中使用它

public displayString:string = "<svg><text data-card-text>Value I want to update</text></svg>";

答案 3 :(得分:2)

此操作不需要任何角度功能。一种方法是构造一个正则表达式来匹配你的字符串并检索值。

但是,您也可以使用外部字符串创建元素并提取其innerText:

let div = document.createElement('div');
// when the string value changes
div.innerHTML = '<svg><text data-card-text>Value I want to update</text></svg>';

并在组件中,将displayString属性设置为此值:

this.displayString = div.innerText;

答案 4 :(得分:1)

那么,如果我理解正确,你想更新<text data-card-text/>元素中的字符串值吗?

如果是这样,您需要使用正则表达式来提取元素内的字符串。输出需要保存在变量中(即displayString)。

可以通过以下方式将变量添加到模板中: <div>{{displayString}}</div>

答案 5 :(得分:1)

我做类似的事情来显示由外部应用程序构造的html文件。

我使用包装器组件,传入html作为输入参数并实现 ngOnChanges 生命周期钩子,让Angular知道html发生了变化。

import { Component, Input, ElementRef, OnChanges } from '@angular/core';

@Component({
  selector: 'result-wrapper',
  template: `<div data-container></div>`
})
export class ResultWrapper implements OnChanges {

  @Input() displayString: string;

  constructor(
    private elementRef: ElementRef,
  ) {}

  ngOnChanges() {
    this.setPageContent();
  }

  setPageContent() {
    const outerDiv = this.elementRef.nativeElement.querySelector('div[data-container]');
    outerDiv.innerHTML = this.displayString;
  }
}

原始html的更改在ResultWrapper的父组件中进行,并通过属性传入 我使用标准文档方法,因为这些看起来最方便。例如:

const tempDiv = document.createElement('div');
tempDiv.innerHTML = displayString;
const dataCardText = tempDiv.querySelector('text[data-card-text]');
dataCardText.value = this.myValue;
return tempDiv.innerHTML;

另外请注意,如果要为displayString设置样式,则应该直接向其添加样式标记,因为Angular将在更新内部html之前应用@Component中定义的样式。请注意,样式可以“渗透”到页面的其他部分,因此请确保它们引用包装器模板中的data-container属性。

我假设标签<svg><text data-card-text>在运行时可能会有所不同,如果不是,您最好将它们放在模板中并插入值。这不需要包装器组件,因为{{myValue}}会自动检测到更改。

@Component({
  selector: 'my-selector',
  template: `<svg><text data-card-text>{{myValue}}</text></svg>`
})