Bind content containing html tags

2019-01-15 17:48发布

问题:

How can I display content containing html tags like <br> inside a polymer-element like:

<polymer-element name="my-element">
  <template>
    {{mylongtext}}
  </template>
<script ...></script>
</polymer-element>
@CustomTag("my-element")
class MyElement extends PolymerElement {
  @observable string mylongtext = "bla bla <br> bla bla <strong> bla </strong>";
}

Currently those tags are shown as text.

回答1:

As you mention, mylongtext is simply displayed as a string, it's not specifically an element or even mark up. However what we can do is automatically call a function any time that our observable is changed. In the callback we create a DocumentFragment which is based off of the contents of the string, and then insert that into our div container.

<polymer-element name="my-element">
  <template>
    <div id="container">

    </div>
  </template>
<script ...></script>
</polymer-element>
@CustomTag("my-element")
class MyElement extends PolymerElement {
  @observable string mylongtext = "bla bla <br> bla bla <strong> bla </strong>";

  MyElement() {
    // Bind property changes to the mylongtext observable string and 
    onPropertyChange(this, #mylongtext, addFragment);
  }

  // Need to do it on inserted to ensure we add the initial value.
  void inserted() {
    super.inserted();
    addFragment();
  }

  void addFragment() {
    var df = new DocumentFragment.html(mylongtext);
    // In the clear any contents from container and add new fragment
    $['container'].nodes..clear()..add(df);
  }

}

Note that onPropertyChange and the $[..] automatic node finding require Polymer dart 0.8.0 or higher (in previous versions it's bindProperty and using shadowRoot.query(..) respectively).

One thing to keep in mind however, is that using DocumentFragment.html() and other similar string-to-html parsers is that they are subject to Sanitization as discussed in this breaking change.



回答2:

This was in web-ui, but is not yet supported in polymer and thus not in polymer.dart yet either. Idea from the mailing list was to create a safe-html element:

<safehtml>{{bindSafeHtmlHere}}</safehtml>