tag - change title router angular2




Ligação HTML angular (12)

A maneira de adicionar dinamicamente elementos ao DOM, como explicado no documento Angular 2, é usando a classe ViewContainerRef de @ Angular / core.

O que você precisa fazer é declarar uma diretiva que implementará o ViewContainerRef e agirá como um espaço reservado no seu DOM.

Directiva

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appInject]'
})
export class InjectDirective {

  constructor(public viewContainerRef: ViewContainerRef) { }

}

Então, no modelo em que você deseja injetar o componente:

HTML

<div class="where_you_want_to_inject">    
  <ng-template appInject></ng-template>
</div>

Então, a partir do código do componente injetado, você irá injetar o componente que contém o HTML desejado:

import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { InjectDirective } from '../inject.directive';
import { InjectedComponent } from '../injected/injected.component';

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

  @ViewChild(InjectDirective) injectComp: InjectDirective;

  constructor(private _componentFactoryResolver: ComponentFactoryResolver) {
  }

  ngOnInit() {
  }

  public addComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.createComponent(componentFactory);
  }

  public removeComp() {
    const componentFactory = this._componentFactoryResolver.resolveComponentFactory(InjectedComponent);
    const viewContainerRef = this.injectComp.viewContainerRef;
    const componentRef = viewContainerRef.remove();
  }

}

Eu adicionei um aplicativo de demonstração totalmente funcional no Angular 2 adicionar dinamicamente o componente à demonstração do DOM

Estou escrevendo um aplicativo Angular e tenho uma resposta HTML que desejo exibir.

Como faço isso? Se eu simplesmente usar a sintaxe de ligação {{myVal}} ela codificará todos os caracteres HTML (é claro).

Eu preciso de alguma forma para ligar o innerHTML de um div para o valor da variável.



Basta usar o atributo [innerHTML] no seu HTML , algo assim abaixo:

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

Já teve propriedades em seu componente que contêm alguma marcação html ou entidades que você precisa exibir em seu modelo? A interpolação tradicional não funciona, mas a ligação da propriedade innerHTML vem para o resgate.

Usando o {{myVal}} NÃO funciona como esperado! Isso não vai pegar as tags HTML como <p> , <strong> etc e passá-lo apenas como strings ...

Imagine que você tenha esse código no seu componente:

const myVal:string ='<strong></strong> is <em>helpful!</em>'

Se você usa {{myVal}} , você verá isso na exibição:

<strong></strong> is <em>helpful!</em>

mas usando [innerHTML]="myVal" faz o resultado como esperado assim:

é útil!


Em Angular 2 você pode fazer 3 tipos de ligações:

  • [property]="expression" -> Qualquer propriedade html pode ser vinculada a um
    expressão. Nesse caso, se a propriedade de alterações de expressão for atualizada, isso não funcionará de outra maneira.
  • (event)="expression" -> Quando o evento é ativado, executa a expressão.
  • [(ngModel)]="property" -> Associa a propriedade de js (ou ts) a html. Qualquer atualização nesta propriedade será perceptível em todos os lugares.

Uma expressão pode ser um valor, um atributo ou um método. Por exemplo: '4', 'controller.var', 'getValue ()'

Exemplo here



Nós sempre podemos passar o conteúdo html para a propriedade innerHTML para renderizar conteúdo dinâmico HTML, mas esse conteúdo html dinâmico também pode ser infectado ou malicioso. Portanto, antes de passar conteúdo dinâmico para innerHTML , devemos sempre garantir que o conteúdo seja higienizado (usando o DOMSanitizer ) para que possamos escapar de todo o conteúdo mal-intencionado.

Tente abaixo do tubo:

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";

@Pipe({name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }
    transform(value: string) {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }
}

Usage:
<div [innerHTML]="content | safeHtml"></div>

Peço desculpas se estou perdendo o ponto aqui, mas gostaria de recomendar uma abordagem diferente:

Acho melhor retornar os dados brutos do aplicativo do lado do servidor e vinculá-los a um modelo no lado do cliente. Isso faz com que as solicitações sejam mais ágeis, já que você só está retornando o json do seu servidor.

Para mim, parece que não faz sentido usar o Angular se tudo o que você está fazendo é buscar o html do servidor e injetá-lo "como está" no DOM.

Eu sei Angular 1.x tem uma ligação HTML, mas eu não vi uma contrapartida no Angular 2.0 ainda. Eles podem adicioná-lo mais tarde. De qualquer forma, eu ainda consideraria uma API de dados para o seu aplicativo Angular 2.0.

Eu tenho algumas amostras aqui com alguma ligação de dados simples, se você estiver interessado: http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples


Se você quer isso em Angular 2 ou Angular 4 e também quer manter CSS inline, então você pode usar

<div [innerHTML]="theHtmlString | keepHtml"></div>

Usar o [innerHTML] diretamente sem usar o saneante DOM do Angular não é uma opção se ele contiver conteúdo criado pelo usuário. O tubo safeHtml sugerido por @ GünterZöchbauer em sua resposta é uma maneira de sanear o conteúdo. A seguinte diretiva é outra:

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);
    }
  }
}

Ser usado

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

Você pode usar este método

<div [innerHTML]=var></div>

ou ligá-lo por id

 <div #html></div>

e no componente

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;
    }
}

[innerHtml] é uma ótima opção na maioria dos casos, mas falha com strings realmente grandes ou quando você precisa de um estilo codificado em html.

Eu gostaria de compartilhar outra abordagem:

Tudo o que você precisa fazer é criar um div em seu arquivo html e dar um id:

<div #dataContainer></div>

Em seguida, no seu componente Angular 2, crie uma referência a esse objeto (TypeScript aqui):

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;
    }
}

Em seguida, basta usar a função loadData para acrescentar algum texto ao elemento html.

É apenas uma maneira de fazer isso usando javascript nativo, mas no ambiente Angular. Eu não recomendo, porque torna o código mais bagunçado, mas às vezes não há outra opção.

Veja também .com/questions/36265026/…


Angular 2.0.0 e Angular 4.0.0 final

Para conteúdo seguro apenas

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

DOMSanitizer

HTML potencial inseguro precisa ser explicitamente marcado como confiável usando o desinfetante de DOM da Angulars, portanto, não tira partes potencialmente inseguras do conteúdo

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

com um cachimbo como

@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
  }
}

Veja também No RC.1 alguns estilos não podem ser adicionados usando a sintaxe de ligação

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

Aviso de segurança

Confiar no usuário adicionou HTML pode representar um risco de segurança. Os documentos mencionados acima afirmam:

Chamar qualquer uma das APIs bypassSecurityTrust... desativa a sanitização integrada do Angular para o valor passado. Verifique e audite cuidadosamente todos os valores e caminhos de código que entram nessa chamada. Certifique-se de que quaisquer dados do usuário sejam escapados adequadamente para este contexto de segurança. Para mais detalhes, consulte o Guia de Segurança .

Marcação angular

Algo como

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

com

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

não fará com que o Angular processe nada específico do Angular no foo . Angular substitui a marcação específica Angular no momento da criação pelo código gerado. A marcação adicionada no tempo de execução não será processada pelo Angular .

Para adicionar HTML que contenha marcação específica para Angular (ligação de propriedade ou valor, componentes, diretivas, pipes, ...), é necessário adicionar o módulo dinâmico e compilar os componentes no tempo de execução. Esta resposta fornece mais detalhes Como posso usar / criar um modelo dinâmico para compilar o componente dinâmico com o Angular 2.0?





angular2-databinding