Как получить ng-template innerHTML для компонента

Я хочу получить innerHTML ng-template для своего компонента. Что-то типа

HTML

<my-comp [template]="myTemplate"></my-comp>
<ng-template #myTemplate></ng-template> 

TS

export class MyComponent implements OnInit {

  @Input() template: string | TemplateRef<any>;

  ngOnInit(){
    console.log(this.template);
  }

}

person Sibiraj    schedule 10.11.2017    source источник
comment
просто чтобы уточнить: вы хотите, чтобы html, предоставленный родительским компонентом, использовался в качестве шаблона дочернего компонента?   -  person BeetleJuice    schedule 10.11.2017
comment
да .. мы можем получить шаблон, если внутри компонента (используя viewChild). но как это сделать, если шаблон не является частью компонента @BeetleJuice   -  person Sibiraj    schedule 10.11.2017
comment
Таким образом, сам компонент представляет собой просто пустую оболочку, пока шаблон не будет предоставлен извне.   -  person BeetleJuice    schedule 10.11.2017
comment
вы хотите отправить HTML-контент в качестве входных данных из другого компонента и привязать к шаблону? правильный?   -  person Aravind    schedule 10.11.2017
comment
Нет точно не может быть пустой оболочкой. Но может быть. Если эта проблема решится. Его можно использовать по-разному, как даже пустую оболочку. Могут быть пользовательские шаблоны и т. д. @BeetleJuice   -  person Sibiraj    schedule 10.11.2017
comment
вы можете получить innerHTML, только если он имеет тип ElementRef или ViewChild. Также @Input не может быть TemplateRef, поэтому, если ваше требование будет разработано, я предложу вам способы реализации   -  person Aravind    schedule 10.11.2017
comment
да @Аравинд...   -  person Sibiraj    schedule 10.11.2017
comment
@SibiRaj Прости, я не понял тебя   -  person Aravind    schedule 10.11.2017
comment
Это было для вашего предыдущего комментария @Aravind   -  person Sibiraj    schedule 10.11.2017
comment
@Аравинд. Я видел что-то похожее на мое требование, но я не могу точно понять это. проверьте здесь github.com/ng- bootstrap/ng-bootstrap/blob/   -  person Sibiraj    schedule 10.11.2017
comment
Давайте продолжим обсуждение в чате.   -  person Aravind    schedule 10.11.2017


Ответы (2)


Поскольку вам требуется только оболочка, в которую будет внедрен шаблон, рассмотрите возможность использования директивы вместо компонента.

@Directive({
  selector: '[template-host]'
})
export class HostDirective{

  @Input('template-host') set templateHtml(value){
    this.hostElement.innerHTML = value;
  }

  private hostElement:HTMLElement;

  constructor(elementRef:ElementRef){
    this.hostElement = elementRef.nativeElement;
  }
}

Теперь вы можете применить эту директиву к любому элементу, и предоставленная привязка template-host вызовет внедрение html в этот элемент. Например:

<!-- The div will contain the html in myTemplate -->
<div [template-host]="myTemplate"></div>

Текущая демонстрация

Если у вашего класса действительно есть шаблон, но вы хотите внедрить html только в часть этого шаблона, узнать о включении

person BeetleJuice    schedule 10.11.2017
comment
Спасибо. но это дает шаблон элемента хоста, но я хочу от ng-template - person Sibiraj; 10.11.2017
comment
Я понимаю. Почему бы не сохранить шаблон как строковое свойство родительского компонента? Почему вы требуете, чтобы он находился внутри ng-template в родительском представлении? - person BeetleJuice; 10.11.2017
comment
Итак, вы имеете в виду просто обычную строку? - person Sibiraj; 10.11.2017
comment
@SibiRaj Да: любую html-строку, которую вы бы написали в шаблоне, храните в виде простой строки в свойстве класса. - person BeetleJuice; 11.11.2017
comment
Ссылка мертва - person Johan Aspeling; 06.02.2019
comment
Этот подход не работает в Angular 8. Я получаю следующую строку текста, добавленную к innerHTML. ` (см. g.co/ng/security#xss)` Попробуйте вместо этого использовать стандартную директиву . - person DeanB_Develop; 14.10.2019
comment
Можно ли пройти ngTemplateOutletContext? - person Jeremy; 12.04.2021

Сегодня мне нужно было решить точно такую ​​​​же проблему, и я нашел этот вопрос. В итоге я изучил ng-bootstrap, чтобы посмотреть, как они это сделали, и в конечном итоге это довольно простое решение.

Вам нужно получить ViewContainerRef, в который вы хотите вставить строку/TemplateRef. Это может быть либо хост-элемент (ViewContainerRef, внедренный в конструктор), либо ViewChild. например:

constructor(private viewContainerRef: ViewContainerRef) { }

or

@ViewChild('someDiv', {read: ViewContainerRef}) viewContainerRef: ViewContainerRef;

затем в ngOnInit() вам нужно сделать if/else в зависимости от того, является ли ввод TemplateRef или строкой, и назначить его для viewContainerRef:

if (this.template instanceof TemplateRef) {
   this.viewContainerRef.createEmbeddedView(<TemplateRef<any>>this.template);
} else {
    this.viewContainerRef.element.nativeElement.innerHTML = this.template;
}

Надеюсь, это поможет!

person nonstopcoding    schedule 08.05.2018