Angular HTML binding

后端 未结 21 2695
暖寄归人
暖寄归人 2020-11-21 04:00

I am writing an Angular application and I have an HTML response I want to display.

How do I do that? If I simply use the binding syntax {{myVal}} it en

相关标签:
21条回答
  • 2020-11-21 04:49

    [innerHtml] is great option in most cases, but it fails with really large strings or when you need hard-coded styling in html.

    I would like to share other approach:

    All you need to do, is to create a div in your html file and give it some id:

    <div #dataContainer></div>
    

    Then, in your Angular 2 component, create reference to this object (TypeScript here):

    import { Component, ViewChild, ElementRef } from '@angular/core';
    
    @Component({
        templateUrl: "some html file"
    })
    export class MainPageComponent {
    
        @ViewChild('dataContainer') dataContainer: ElementRef;
    
        loadData(data) {
            this.dataContainer.nativeElement.innerHTML = data;
        }
    }
    

    Then simply use loadData function to append some text to html element.

    It's just a way that you would do it using native javascript, but in Angular environment. I don't recommend it, because makes code more messy, but sometimes there is no other option.

    See also Angular 2 - innerHTML styling

    0 讨论(0)
  • 2020-11-21 04:50

    On angular2@2.0.0-alpha.44:

    Html-Binding will not work when using an {{interpolation}}, use an "Expression" instead:

    invalid

    <p [innerHTML]="{{item.anleser}}"></p>
    

    -> throws an error (Interpolation instead of expected Expression)

    correct

    <p [innerHTML]="item.anleser"></p>
    

    -> this is the correct way.

    you may add additional elements to the expression, like:

    <p [innerHTML]="'<b>'+item.anleser+'</b>'"></p>
    

    hint

    HTML added using [innerHTML] (or added dynamically by other means like element.appenChild() or similar) won't be processed by Angular in any way except sanitization for security purposed.
    Such things work only when the HTML is added statically to a components template. If you need this, you can create a component at runtime like explained in How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

    0 讨论(0)
  • 2020-11-21 04:51

    Angular 2.0.0 and Angular 4.0.0 final

    For safe content just

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

    DOMSanitizer

    Potential unsafe HTML needs to be explicitly marked as trusted using Angulars DOM sanitizer so doesn't strip potentially unsafe parts of the content

    <div [innerHTML]="myVal | safeHtml"></div>
    

    with a pipe like

    @Pipe({name: 'safeHtml'})
    export class Safe {
      constructor(private sanitizer:DomSanitizer){}
    
      transform(style) {
        return this.sanitizer.bypassSecurityTrustHtml(style);
        //return this.sanitizer.bypassSecurityTrustStyle(style);
        // return this.sanitizer.bypassSecurityTrustXxx(style); - see docs
      }
    }
    

    See also In RC.1 some styles can't be added using binding syntax

    And docs: https://angular.io/api/platform-browser/DomSanitizer

    Security warning

    Trusting user added HTML may pose a security risk. The before mentioned docs state:

    Calling any of the bypassSecurityTrust... APIs disables Angular's built-in sanitization for the value passed in. Carefully check and audit all values and code paths going into this call. Make sure any user data is appropriately escaped for this security context. For more detail, see the Security Guide.

    Angular markup

    Something like

    class FooComponent {
      bar = 'bar';
      foo = `<div>{{bar}}</div>
        <my-comp></my-comp>
        <input [(ngModel)]="bar">`;
    

    with

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

    won't cause Angular to process anything Angular-specific in foo. Angular replaces Angular specific markup at build time with generated code. Markup added at runtime won't be processed by Angular.

    To add HTML that contains Angular-specific markup (property or value binding, components, directives, pipes, ...) it is required to add the dynamic module and compile components at runtime. This answer provides more details How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

    0 讨论(0)
  • 2020-11-21 04:51

    You can also bind the angular component class properties with template using DOM property binding.

    Example: <div [innerHTML]="theHtmlString"></div>

    Using canonical form like below:

    <div bind-innerHTML="theHtmlString"></div>
    

    Angular Documentation: https://angular.io/guide/template-syntax#property-binding-property

    See working stackblitz example here

    0 讨论(0)
  • 2020-11-21 04:51

    If you have templates in your angular (or whatever framework) application, and you return HTML templates from your backend through a HTTP request/response, you are mixing up templates between the frontend and the backend.

    Why not just leave the templating stuff either in the frontend (i would suggest that), or in the backend (pretty intransparent imo)?

    And if you keep templates in the frontend, why not just respond with JSON for requests to the backend. You do not even have to implement a RESTful structure, but keeping templates on one side makes your code more transparent.

    This will pay back when someone else has to cope with your code (or even you yourself are re-entering your own code after a while)!

    If you do it right, you will have small components with small templates, and best of all, if your code is imba, someone who doesn't know coding languages will be able to understand your templates and your logic! So additionally, keep your functions/methods as small you can. You will eventually find out that maintaining, refactoring, reviewing, and adding features will be much easier compared to large functions/methods/classes and mixing up templating and logic between the frontend and the backend - and keep as much of the logic in the backend if your frontend needs to be more flexible (e.g. writing an android frontend or switching to a different frontend framework).

    Philosophy, man :)

    p.s.: you do not have to implement 100% clean code, because it is very expensive - especially if you have to motivate team members ;) but: you should find a good balance between an approach to cleaner code and what you have (maybe it is already pretty clean)

    check the book if you can and let it enter your soul: https://de.wikipedia.org/wiki/Clean_Code

    0 讨论(0)
  • 2020-11-21 04:52

    Using [innerHTML] directly without using Angular's DOM sanitizer is not an option if it contains user-created content. The safeHtml pipe suggested by @GünterZöchbauer in his answer is one way of sanitizing the content. The following directive is another one:

    import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
      SimpleChanges } from '@angular/core';
    
    // Sets the element's innerHTML to a sanitized version of [safeHtml]
    @Directive({ selector: '[safeHtml]' })
    export class HtmlDirective implements OnChanges {
      @Input() safeHtml: string;
    
      constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}
    
      ngOnChanges(changes: SimpleChanges): any {
        if ('safeHtml' in changes) {
          this.elementRef.nativeElement.innerHTML =
            this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
        }
      }
    }
    

    To be used

    <div [safeHtml]="myVal"></div>
    
    0 讨论(0)
提交回复
热议问题