在EmbeddedView内访问容器组件的FormGroupDirective

时间:2018-11-30 16:34:19

标签: angular angular-reactive-forms

我越来越不时地获得关于反应式实际工作方式的更多见解,我仍然试图找出实际发生的情况以及如何使某种情况发生。例如,我目前正在尝试创建可重用的组件并通过嵌入式视图添加输入字段。

不幸的是,我总是收到关于必须将我的formControlName与父formGroup指令一起使用的错误。为了防止在投影内容之前就发生此错误,我将内容包装在ng模板中,并将其实例移动到显示投影内容的子组件中。但是它仍然抱怨没有表单组指令。

因此,我的问题是:如何以注入器的方式处理ng-content或ng-template,请问我做错了正确的方向吗?

我还尝试创建一个指令,将其放在ng-container上,并通过select distinct entity_id,oldest_item_id,newest_item_id,signal_count_sum from (select t.* ,sum(signal_count) over(partition by entity_id) as signal_sum ,first_value(item_id) over(partition by entity_id order by month_id,item_id rows unbounded preceding) as oldest_item_id ,first_value(item_id) over(partition by entity_id order by month_id desc,item_id rows unbounded preceding) as newest_item_id from tbl t ) t 注入了现存的FormGroup指令。没有运气。

为了更好地了解实际情况,我创建了一个堆栈闪电:https://stackblitz.com/edit/angular-uuvbrg

非常感谢您的时间和精力!

1 个答案:

答案 0 :(得分:1)

对于动态创建的视图,Angular区分两种类型:

  • 声明视图-声明模板的视图

  • 插入视图-插入模板的视图

这里的主要规则是 上下文是从继承的    声明视图树,而不是插入视图树。

这意味着拥有一个模板,例如:

<app-form-list-item>
  <ng-template #someChild>
    <input type="text" formControlName="myUsername">
  </ng-template>
</app-form-list-item>

我们应该确保formControlName指令可以找到ControlContainer从该模板而不是app-form-list-item内部的模板开始的依赖关系攀爬树。

在此处form-list-item.component.html中使用ControlContainer提供程序放置任何指令都无济于事,因为formControlName是在父组件中声明的。

一种解决方法是在您的ControlContainer上提供FormListItemComponent:这可能是可行的,并且不需要在父组件中编写代码。

form-list-item.component.html

<form #ngForm="ngForm" ...

form-list-item.component.ts

@Component({
  ...
  providers: [
    {
      provide: ControlContainer,
      useFactory: (comp: FormListItemComponent) => comp.ngForm,
      deps: [FormListItemComponent] 
    }
  ]
})
export class FormListItemComponent implements AfterContentInit {
  ...
  @ViewChild('ngForm') ngForm: FormGroupDirective;

它将导致

<app-form-list-item>    <=== ControlContainer that points to inner FormGroupDirective
 /\
 ||   <ng-template #someChild>
 ||
 ||     <input type="text" formControlName="myUsername">

仅当您将内容包装在模板中时,此方法才有效,否则ControlContainer将指向空的FormGroupDirective

Forked Stackblitz

另请参阅: