Есть ли способ получить доступ к переменным @Input в динамически создаваемом компоненте?

#angular

#angular

Вопрос:

Я динамически добавляю строки в форму и хочу, чтобы каждая новая строка имела уникальный идентификационный номер.

У меня есть следующий код для добавления нового компонента (представляющего новую строку), но я обнаружил, что он component.instance содержит только «обычные» свойства вновь созданного компонента, а не свойства, украшенные @Input() . Есть ли какой-либо способ динамической записи / изменения @Input() свойств? Когда динамически создается компонент, естественно предположить, что должен быть простой способ каким-то образом предоставить значения @Input()!

 const componentFactory = this.componentFactoryResolver.resolveComponentFactory(thisType);
const component = this.subEnrollForm.container.createComponent(componentFactory);
component.instance.rowData.push(newRow); //rowData is a property in the
                                       dynamically-created component and 
                                       is decorated with @Input()
  

Вот динамически создаваемый компонент:

 export class SubEnrollFormRowComponent implements OnInit, DoCheck, OnChanges, AfterContentInit, AfterViewInit {
 @Input() rowData; 
  objKeys: Array<any> = [];
  subKeys: Array<any> = [];
  

Я видел старую публикацию, в которой был следующий ответ, но я надеюсь, что впоследствии были добавлены новые функции для решения этой проблемы:

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

Для всех других ситуаций используйте общие службы, как описано вhttps://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

Вы также можете использовать

пусть ComponentRef = entryPoint.createComponent(ComponentFactory); ComponentRef.instance.someProp = ‘someValue’; ComponentRef.instance.someObservableOrEventEmitter.subscribe(данные => this.prop = данные);

Это последнее решение не сработало для меня, как и другое предложение привести компонент к типу <any> . Моя интерпретация services подхода, упомянутого выше, заключается в том, что мне нужно было бы создать Observable для подписки внука, чтобы отслеживать, когда бабушка и дедушка пытаются обновить свойство внука @Input(), но этот подход кажется мне огромным излишеством с большим количеством ненужного кодирования и накладных расходов для достижения чего-то, что должно быть очень простым и понятный (если я чего-то не упускаю, что очень вероятно!). Заранее большое спасибо, если у кого-нибудь есть относительно простой способ инициализировать / динамически изменять свойство компонента внука, которое украшено @Input!

Комментарии:

1. Одним из решений может быть добавление свойства, которое не оформлено с помощью @Input, а затем использовать это свойство для обновления @Input свойства в последующем цикле жизненного цикла . , , но опять же, это похоже на небольшой взлом, и я хотел бы знать, есть ли более элегантный / прямой способ обновления / записи в @Input свойства . , ,

2. Это всегда было возможно. Рабочий пример из документации angular: angular.io/generated/live-examples/dynamic-component-loader /… . Компоненты hero-job-ad и hero-job-profile создаются динамически с их @Input() data свойствами, установленными во время выполнения.

Ответ №1:

Свойства, оформленные с помощью @Input , по-прежнему являются свойствами класса и доступны, как и любое другое свойство.

Я создал рабочий пример:https://stackblitz.com/edit/angular-6-template-yih3sx?file=src/app/app.component.ts

Комментарии:

1. Очень хороший пример.

2. Большое спасибо и высоко ценится! Итак, если я не ошибаюсь, похоже, что хитрость заключается в: (<AdComponent>componentRef.instance).data = adItem.data; где мы преобразуем компонент с @Input в другой тип, где data свойство не украшено @Input . . . Дьявольски умно!

3. Это не является обязательным требованием. Пример Angular делает это, потому что их пример немного сложнее. Если вы посмотрите на мой пример, я выполняю кастинг в DynamicComponent , который все еще имеет @Input декоратор и все еще работает. Декоратор никак не влияет на свойства / скрывает их.