Angular 6 с ngComponentOutlet и привязкой / обновлением данных
Я много читал о том, что ngComponentOutlet не работает с привязкой, но, насколько я понял, во всех случаях требовалось что-то вроде дочернего <-> родительского связывания / связи (@Input и @Output, и для этого есть ng-dynamic-component, который работает). Я думаю, что мой случай немного проще, я просто хочу обновить привязку между динамически созданными компонентами и их собственными шаблонами.
Кстати, я прочитал эти страницы:
Как использовать ngFor для компонентов нескольких типов, используя ngComponentOutlet?
https://github.com/angular/angular/issues/15360
Angular 2 динамических вкладки с выбранными пользователем компонентами
Идея использования ngfor и ngComponentOutlet на основе первой ссылки, проблема описана в ссылках 2. и 3.
Основная идея: создать список, который содержит различные типы, и визуализировать их по-разному на основе своих собственных шаблонов. Эти шаблоны содержат привязки к своим собственным компонентам.
Я собрал минимальный пример, но, к сожалению, я не смог собрать это во plunker, он не работал, так что вот основные части кода.
Обзор небольшого примера кода: у меня есть пустой массив и кнопка, и когда я нажимаю эту кнопку, 2 компонента создаются и вставляются в список. Эти компоненты в списке отображаются с использованием собственного пользовательского шаблона (например, comp-a.component.html). Это все работает:
Топливный HTML-код:
<div>
<div>
<p>This is a static component, with working binding</p>
<div [innerHtml]="staticBindingMemberValue"></div>
<br>
<hr>
</div>
<button type="button" (click)="onclick()">Generate dynamic data</button>
<hr>
<div *ngFor="let contentItem of arrayContent" style="border: solid 1px; padding: 20px;margin: 20px;">
<ng-container *ngComponentOutlet="contentItem.component"></ng-container>
</div>
</div>
Код компонента Toplevel:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
arrayContent:any[] = [];
staticBindingMemberValue:string = "Initial value for Static comp"
onclick() {
let a = new CompAComponent();
let b = new CompBComponent();
a.init("NEW value for A")
b.init("NEW value for B")
this.staticBindingMemberValue = "NEW value for Static comp"
this.arrayContent.push(a)
this.arrayContent.push(b)
}
}
Пример компонента 'A' (B практически одинаков):
export class CompAComponent implements OnInit {
component = CompAComponent;
title:string = "Initial value for A"
constructor() { }
ngOnInit() {
}
init(newValue) {
this.title = newValue
}
}
Компоненты имеют собственный HTML-шаблон (не может быть проще):
<p [innerHtml]="title"></p>
Как видите, элемент 'title' имеет начальное значение, но в методе click() я вызываю методы 'init' для компонентов и пытаюсь установить новое значение. Проблема в том, что привязка данных работает, но не обновляется, поэтому список отображается со строкой "Начальное значение для A", а newValue просто задается в коде позади, но страница не обновляется. Между тем, обновление "staticBindingMemberValue" работает:
Вот так это выглядит после нажатия на кнопку
Я прочитал много способов динамического создания компонентов, я могу что-то неправильно понять, поэтому мой вопрос:
В Angular 6 до сих пор нет способа заставить это чрезвычайно простое создание динамического компонента работать?
Как я могу заставить эту работу работать, поэтому, когда что-то происходит ваааае после создания компонента (вызывается метод click, некоторые службы получают данные с сервера и т. Д.), Привязки обновляются:
я должен использовать другой способ для динамического создания компонентов?
я должен создать привязку данных по-другому?
Спасибо
[ОБНОВИТЬ]
Хорошо, я нашел способ сделать это с помощью фабричного распознавателя, но это не то же самое, и немного хакерски. Есть идеи об этом подходе?