Estou escrevendo um aplicativo Angular e tenho uma resposta HTML que quero exibir.
Como faço isso? Se eu simplesmente usar a sintaxe de ligação, {{myVal}}
ele codifica todos os caracteres HTML (é claro).
Eu preciso de alguma forma vincular o innerHTML
de div
a ao valor da variável.
Respostas:
A sintaxe correta é a seguinte:
Referência da documentação
fonte
Angular 2.0.0 e Angular 4.0.0 final
Para conteúdo seguro apenas
DOMSanitizer
O HTML não seguro em potencial precisa ser explicitamente marcado como confiável usando o Sanitizer DOM da Angulars, para não remover partes do conteúdo potencialmente inseguras
com um cano como
Veja também No RC.1, alguns estilos não podem ser adicionados usando a sintaxe de ligação
E documentos: https://angular.io/api/platform-browser/DomSanitizer
Aviso de segurança
Confiar no HTML adicionado pelo usuário pode representar um risco à segurança. Os documentos mencionados anteriormente afirmam:
Marcação angular
Algo como
com
não fará com que o Angular processe nada específico do Angular
foo
. Angular substitui a marcação específica angular no tempo de compilaçã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 angular (associação de propriedade ou valor, componentes, diretivas, pipes, ...), é necessário adicionar o módulo dinâmico e compilar componentes em 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?
fonte
import { BrowserModule, DomSanitizer } from '@angular/platform-browser'
import { Pipe } from '@angular/core'
[innerHtml]
é uma ótima opção na maioria dos casos, mas falha com cadeias 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 uma div no seu arquivo html e fornecer um ID:
Em seguida, no seu componente Angular 2, crie referência a este objeto (TypeScript aqui):
Em seguida, basta usar a
loadData
função para acrescentar algum texto ao elemento html.É apenas uma maneira de fazer isso usando javascript nativo, mas em ambiente Angular. Eu não recomendo, porque torna o código mais confuso, mas às vezes não há outra opção.
Veja também Angular 2 - estilo innerHTML
fonte
nativeElement
diretamente as propriedades, o que é considerado uma má prática. Tenho certeza de que[innerHTML]="..."
faz o mesmo sob o capô, mas na prática do Angular2.[innerHTML]
grandes seqüências de caracteres no Angular2?[innerHtml]
remove o estilo codificado no HTML. Para integrar um editor wysiwyg, tive que usar a abordagem listada aqui.[innerHTML]
abordagem não.Em [email protected]:
Html-Binding não funcionará ao usar um
{{interpolation}}
, use uma "Expressão":inválido
-> gera um erro (interpolação em vez da expressão esperada)
corrigir
-> esta é a maneira correta.
você pode adicionar elementos adicionais à expressão, como:
dica
O HTML adicionado usando
[innerHTML]
(ou adicionado dinamicamente por outros meios semelhanteselement.appenChild()
ou similares) não será processado pela Angular de forma alguma, exceto pela higienização por segurança.Essas coisas funcionam apenas quando o HTML é adicionado estaticamente a um modelo de componentes. Se você precisar disso, poderá criar um componente em tempo de execução, como explicado em Como posso usar / criar um modelo dinâmico para compilar o Componente dinâmico com o Angular 2.0?
fonte
Usar o [innerHTML] diretamente sem usar o desinfetante DOM da Angular não é uma opção se ele contiver conteúdo criado pelo usuário. O canal safeHtml sugerido por @ GünterZöchbauer em sua resposta é uma maneira de higienizar o conteúdo. A seguinte diretiva é outra:
Ser usado
fonte
Can't bind to 'safeHtml' since it isn't a known property of 'div'.
ng-versão 2.4.4constructor( private sanitizer: Sanitizer) {}
e vincular o resultado ao que for necessário, também o uso de ElementRef é fortemente sugerido.Isso funciona para mim:
<div innerHTML = "{{ myVal }}"></div>
(Angular2, Alpha 33)De acordo com outro SO: Inserir HTML do servidor no DOM com angular2 (manipulação geral do DOM no Angular2) , "html interno" é equivalente a "ng-bind-html" no Angular 1.X
fonte
Apenas para obter uma resposta completa, se o seu conteúdo html estiver em uma variável de componente, você também poderá usar:
fonte
Peço desculpas se estou perdendo o ponto aqui, mas gostaria de recomendar uma abordagem diferente:
Eu acho que é melhor retornar dados brutos do aplicativo do servidor e vinculá-los a um modelo no lado do cliente. Isso gera solicitações mais ágeis, pois você está retornando apenas o json do seu servidor.
Para mim, não parece fazer sentido usar o Angular se tudo o que você está fazendo é buscar html no servidor e injetá-lo "como está" no DOM.
Eu sei que o Angular 1.x tem uma ligação html, mas ainda não vi uma contraparte no Angular 2.0. 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
fonte
A resposta curta já foi fornecida aqui: use
<div [innerHTML]="yourHtml">
binding.No entanto, o restante dos conselhos mencionados aqui pode ser enganoso. O Angular possui um mecanismo de desinfecção incorporado quando você vincula a propriedades como essa. Como o Angular não é uma biblioteca de desinfecção dedicada, é muito zeloso em relação a conteúdo suspeito não correr riscos. Por exemplo, ele limpa todo o conteúdo SVG em uma sequência vazia.
Você pode ouvir conselhos para "limpar" seu conteúdo usando
DomSanitizer
para marcar o conteúdo como seguro nosbypassSecurityTrustXXX
métodos. Também existem sugestões para usar pipe para fazer isso, e esse pipe é frequentemente chamadosafeHtml
.Tudo isso é enganoso, porque na verdade ignora a higienização , não a higienização do seu conteúdo. Isso pode ser uma preocupação de segurança, porque se você fizer isso no conteúdo fornecido pelo usuário ou em qualquer coisa que não tenha certeza - você se abrirá para ataques de código malicioso.
Se o Angular remover algo que você precisa com a higienização interna - o que você pode fazer em vez de desabilitar é delegar a higienização real a uma biblioteca dedicada que seja boa nessa tarefa. Por exemplo - DOMPurify.
Eu criei uma biblioteca de wrapper para ele, para que pudesse ser facilmente usada com Angular: https://github.com/TinkoffCreditSystems/ng-dompurify
Ele também possui um canal para higienizar declarativamente o HTML:
A diferença para os pipes sugeridos aqui é que ele realmente faz a higienização por meio do DOMPurify e, portanto, funciona para o SVG.
Uma coisa a ter em mente é que o DOMPurify é ótimo para higienizar HTML / SVG, mas não CSS. Assim, você pode fornecer o desinfetante CSS da Angular para lidar com CSS:
É um
ɵ
prefixo interno - hense , mas é assim que a equipe do Angular o usa em seus próprios pacotes também. Essa biblioteca também funciona para o Angular Universal e para o ambiente de renomeação do lado do servidor.fonte
Basta usar o
[innerHTML]
atributo no seu HTML , algo como isto abaixo:Usar
{{myVal}}
NÃO funciona como esperado! Isso não pega as tags HTML como etc<p>
,<strong>
e as transmite apenas como strings ...Imagine que você tenha este código em seu componente:
const myVal:string ='<strong>Stackoverflow</strong> is <em>helpful!</em>'
Se você usar
{{myVal}}
, você verá isso na exibição:mas usar
[innerHTML]="myVal"
cria o resultado conforme o esperado da seguinte maneira:Stackoverflow é útil!
fonte
Você pode aplicar vários canais para estilo, link e HTML da seguinte maneira em .html
e no tubo .ts para desinfetante de 'URL'
canal para desinfetante 'HTML'
isso será aplicado sem perturbar nenhum evento de estilo e clique no link
fonte
O innerHtml é uma propriedade dos elementos HTML, que permite definir seu conteúdo html programaticamente. Há também uma propriedade innerText que define o conteúdo como texto sem formatação.
O
[attributeName]="value"
colchete da caixa, ao redor do atributo define uma ligação de entrada Angular. Isso significa que o valor da propriedade (no seu caso innerHtml) está vinculado à expressão especificada. Quando o resultado da expressão é alterado, o valor da propriedade também é alterado.Então, basicamente,
[innerHtml]
você pode vincular e alterar dinamicamente o conteúdo html do elemento HTML fornecido.fonte
No Angular 2, você pode fazer três tipos de ligações:
[property]="expression"
-> Qualquer propriedade html pode vincular a umaexpressão. Nesse caso, se a expressão mudar de propriedade, a atualização será atualizada, mas isso não funcionará da outra maneira.
(event)="expression"
-> Quando o evento é ativado, execute a expressão.[(ngModel)]="property"
-> Vincula a propriedade de js (ou ts) ao 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 aqui
fonte
A maneira de adicionar elementos dinamicamente ao DOM, conforme explicado no documento do Angular 2, é usando a classe ViewContainerRef de @ Angular / core.
O que você precisa fazer é declarar uma diretiva que implementará o ViewContainerRef e aja como um espaço reservado no seu DOM.
Directiva
Em seguida, no modelo em que você deseja injetar o componente:
HTML
Em seguida, no código do componente injetado, você injetará o componente que contém o HTML que deseja:
Adicionei um aplicativo de demonstração totalmente funcional no Angular 2 para adicionar dinamicamente o componente à demonstração do DOM
fonte
Você pode usar várias abordagens para alcançar a solução. Como já foi dito na resposta aprovada, você pode usar:
dependendo do que você está tentando alcançar, também pode tentar outras coisas, como javascript DOM (não recomendado, operações DOM são lentas):
Apresentação
Componente
Vinculação de Propriedade
Javascript DOM HTML externo
fonte
getElementsById
ou qualquer outro método de seleção é ruim porque pode capturar elementos pertencentes a componentes completamente diferentes se eles contiverem elementos com o mesmo ID (ou outro critério).Sempre podemos transmitir conteúdo html à
innerHTML
propriedade para renderizar conteúdo dinâmico html, mas esse conteúdo html dinâmico também pode ser infectado ou malicioso. Portanto, antes de transmitir conteúdo dinâmicoinnerHTML
, devemos sempre garantir que o conteúdo seja higienizado (usandoDOMSanitizer
) para que possamos escapar de todo o conteúdo malicioso.Tente abaixo do pipe:
fonte
style: background-color
todas as coisas podem ser removidas e, portanto, é melhor começar a usar isso desde o início ou você ficará muito confuso mais tarde.Se você deseja isso no Angular 2 ou no Angular 4 e também deseja manter o CSS embutido, pode usar
fonte
Você também pode vincular as propriedades da classe de componente angular ao modelo usando a forma canônica como abaixo:
Documentação angular: https://angular.io/guide/template-syntax#property-binding-property
Veja o exemplo de stackblitz em funcionamento aqui
fonte
Trabalhando no Angular v2.1.1
fonte
<div _ngcontent-luf-0=""></div>
para mim. Odiv
está vazio.Se você possui modelos em seu aplicativo angular (ou qualquer estrutura) e retorna modelos HTML do seu back-end por meio de uma solicitação / resposta HTTP, você está misturando modelos entre o front-end e o back-end.
Por que não deixar o material de modelo no front-end (eu sugeriria isso) ou no back-end (imo bastante intransparente)?
E se você mantiver modelos no front-end, por que não responder com JSON para solicitações ao back-end? Você nem precisa implementar uma estrutura RESTful, mas manter os modelos de um lado torna seu código mais transparente.
Isso será recompensado quando outra pessoa tiver que lidar com seu código (ou até você mesmo estará inserindo seu próprio código depois de um tempo)!
Se você fizer isso corretamente, terá pequenos componentes com modelos pequenos e, o melhor de tudo, se seu código for imba, alguém que não conheça linguagens de codificação poderá entender seus modelos e sua lógica! Além disso, mantenha suas funções / métodos o menor possível. Você acabará descobrindo que manter, refatorar, revisar e adicionar recursos será muito mais fácil comparado a grandes funções / métodos / classes e misturar modelos e lógica entre o front-end e o back-end - e manter o máximo da lógica no back-end. se o seu front-end precisar ser mais flexível (por exemplo, escrevendo um front-end android ou alternando para uma estrutura de front-end diferente).
Filosofia, cara :)
ps: você não precisa implementar código 100% limpo, porque é muito caro - especialmente se você tiver que motivar os membros da equipe;) mas: você deve encontrar um bom equilíbrio entre uma abordagem do código mais limpo e o que você tem (talvez já está bem limpo)
verifique o livro, se puder, e deixe-o entrar em sua alma: https://de.wikipedia.org/wiki/Clean_Code
fonte