Угловой HTML-код привязки


Я пишу Угловое приложение, и у меня есть HTML ответ, который я хочу отобразить.

как мне это сделать? Если я просто использую синтаксис привязки {{myVal}} он кодирует все HTML символы (конечно).

мне нужно как-то привязать внутренний html a div переменной величины.

15 504

15 ответов:

правильный синтаксис следующий:

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

работа в 6.1.9

Документация

угловой 2.0.0 и угловой 4.0.0 финал

для безопасного содержания просто

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

DOMSanitizer

потенциальный небезопасный HTML должен быть явно помечен как доверенный с помощью angulars DOM sanitizer, поэтому не удаляет потенциально опасные части контента

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

с трубой, как

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

см. также в RC.1 некоторые стили могут быть добавлены с помощью привязки синтаксис

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

предупреждение

доверчивый пользователь добавил HTML может представлять угрозу безопасности. До этого указанных документов состояние:

вызов любого bypassSecurityTrust... API-интерфейсы, отключает угловой встроенный очистки на переданное значение. Тщательно проверьте и проверьте все значения и пути кода, входящие в этот вызов. Убедиться любые пользовательские данные соответствующим образом экранируются для этого контекста безопасности. Для получения более подробной информации см. Руководство По Безопасности.

Угловое разметки

что-то вроде

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

С

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

не заставит Angular обрабатывать что-либо Угловое в foo. Angular заменяет угловую специфическую разметку во время сборки сгенерированным кодом. Разметка добавлена во время выполнения не будут обрабатываться Угловой.

чтобы добавить HTML, который содержит угловую разметку (привязка свойств или значений, компоненты, директивы, каналы,...) требуется добавить динамический модуль и компилировать компоненты во время выполнения. Этот ответ предоставляет более подробную информацию как я могу использовать/создать динамический шаблон для компиляции динамического компонента с Angular 2.0?

[innerHtml] это отличный вариант в большинстве случаев, но он терпит неудачу с очень большими строками или когда вам нужен жестко закодированный стиль в html.

Я хотел бы поделиться другой подход:

все, что вам нужно сделать, это создать div в вашем html-файле и дать ему некоторый идентификатор:

<div #dataContainer></div>

затем в вашем угловом компоненте 2 Создайте ссылку на этот объект (TypeScript здесь):

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

тогда просто используйте loadData функция добавления некоторого текста в html элемент.

это просто способ, которым вы могли бы сделать это с помощью собственного javascript, но в угловой среде. Я не рекомендую его, потому что делает код более грязным, но иногда нет другого варианта.

см. также угловой 2-innerHTML стиль

On angular2@2.0.0-alpha.44:

Html-привязка не будет работать при использовании {{interpolation}}, вместо этого используйте "выражение":

недействительным

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

-> выдает ошибку (интерполяция вместо ожидаемого выражения)

правильно

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

-> это правильный путь.

вы можете добавить дополнительные элементы к выражению, например:

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

подсказка

HTML добавлен с помощью [innerHTML] (или добавлено динамически другими средствами, такими как element.appenChild() или подобное) не будет обработано угловым в любом случае за исключением санирования для предназначенной обеспеченности.
Такие вещи работают только тогда, когда HTML добавляется статически в шаблон компонентов. Если вам это нужно, вы можете создать компонент во время выполнения, как описано в как я могу использовать / создать динамический шаблон для компиляции динамического компонента с помощью Угловые 2.0?

это работает для меня: <div innerHTML = "{{ myVal }}"></div> (Angular2, Альфа 33)

по другому так: вставка HTML с сервера в DOM с angular2 (общие манипуляции DOM в Angular2), " inner-html "эквивалентно" ng-bind-html " в Angular 1.X

использование [innerHTML] напрямую без использования дезинфицирующего средства DOM Angular не является вариантом, если он содержит пользовательский контент. Труба safeHtml, предложенная @GünterZöchbauer в ответ это один из способов дезинфекции содержимого. Следующая директива является еще одной:

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

использовать

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

просто чтобы получить полный ответ, если ваш html-контент находится в переменной компонента, вы также можете использовать:

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

Я извиняюсь, если я упускаю момент здесь, но я хотел бы рекомендовать другой подход:

Я думаю, что лучше вернуть необработанные данные из вашего серверного приложения и привязать его к шаблону на стороне клиента. Это делает для более проворных запросов, так как вы только возвращаете json с вашего сервера.

Мне кажется, что нет смысла использовать Angular, если все, что вы делаете, это извлечение html с сервера и ввод его "как есть" в ДОМ.

Я знаю угловой 1.x имеет привязку html, но я еще не видел аналога в Angular 2.0. Они могли бы добавить его позже, хотя. В любом случае, я бы все равно рассмотрел api данных для вашего приложения Angular 2.0.

У меня есть несколько примеров здесь с некоторыми простыми данными привязки, если вы заинтересованы:http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples

просто использовать в своем HTML, что-то вроде этого ниже:

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

когда-либо были свойства в вашем компоненте, которые содержат некоторую разметку html или объекты, которые необходимо отобразить в шаблоне? Традиционный интерполяция не будет работать, но привязка свойства innerHTML приходит к спасение.

используя {{myVal}}не работать, как ожидалось! Это не забрать HTML теги, как <p>,<strong> etc и передать его только как строки...

представьте, что у вас есть этот код в компоненте:

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

если вы используете {{myVal}}, вы получите это в вид:

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

, но через [innerHTML]="myVal"делает результат, как ожидалось, следующим образом:

Stackoverflow и полезно!

работа в AngularJS v2.1. 1

<div [innerHTML]="variable or htmlString">
</div>

способ динамического добавления элементов в DOM, как описано в Angular 2 doc, заключается в использовании класса ViewContainerRef из @Angular/core.

что вам нужно сделать, это объявить директиву, которая будет реализовывать ViewContainerRef и действовать как заполнитель на вашем DOM.

директива

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

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

  constructor(public viewContainerRef: ViewContainerRef) { }

}

затем, в шаблоне, где вы хотите вставить компонент:

HTML

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

затем из введенный код компонента, вы будете вводить компонент, содержащий HTML вы хотите:

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

}

я добавил полностью рабочая демо-приложение угловой 2 динамически добавить компонент в DOM demo

Если у вас есть шаблоны в вашем приложении angular (или любой другой фреймворк), и вы возвращаете HTML-шаблоны из своего бэкэнда через HTTP-запрос/ответ, вы смешиваете шаблоны между интерфейсом и бэкэндом.

Почему бы просто не оставить шаблонный материал либо во фронтенде (я бы предложил это), либо в бэкэнде (довольно непрозрачный imo)?

и если вы храните шаблоны в интерфейсе, почему бы просто не ответить с помощью JSON для запросов к базовая программа. Вам даже не нужно реализовывать структуру RESTful, но сохранение шаблонов на одной стороне делает ваш код более прозрачным.

это окупится, когда кто-то, чтобы справиться с вашим кодом (или даже вы сами возвращаются в свой собственный код через некоторое время)!

Если вы сделаете это правильно, у вас будут небольшие компоненты с небольшими шаблонами, и лучше всего, если ваш код imba, кто-то, кто не знает языков кодирования, сможет понять ваши шаблоны и ваша логика! Поэтому, кроме того, держите свои функции/методы как можно меньше. В конечном итоге вы обнаружите, что поддержание, рефакторинг, обзор и добавление функций будет намного проще по сравнению с большими функциями / методами / классами и смешиванием шаблонов и логики между интерфейсом и бэкэндом - и сохранить как можно больше логики в бэкэнде, если ваш интерфейс должен быть более гибким (например, написание интерфейса android или переключение на другой интерфейс рамки.)

философия, человек :)

p. s.: вам не нужно реализовывать 100% чистый код, потому что это очень дорого - особенно если вам нужно мотивировать членов команды ;) но: вы должны найти хороший баланс между подходом к более чистому коду и тем, что у вас есть (возможно, это уже довольно чисто)

проверьте книгу, если можете, и пусть она войдет в вашу душу: https://de.wikipedia.org/wiki/Clean_Code

на Угловое 2 вы можете сделать 3 вида переплетов:

  • [property]="expression" - > любое свойство html может ссылаться на
    выражение. В этом случае при изменении выражения свойство будет обновляться, но это не работает по-другому.
  • (event)="expression" -> когда событие активирует execute expression.
  • [(ngModel)]="property" - > связывает свойство из js (или ts) в html. Любое обновление этого свойства будет заметно везде.

An выражения может быть значение атрибута или метода. Например: '4', 'контроллер.var', ' getValue ()'

пример здесь

ниже код поможет вам

myval можно заменить на нужный html

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

попробуйте этот код

ваша строка с тегом html, как показано ниже

htmlString:string = "Hello<br/>Html"

вы можете получить строку в HTML-страницы

<ion-content>
<ion-item>
<div [innerHTML] = "'<p>' + htmlString + '</p>'"></div>
</ion-item>
</ion-content>