我有一些动态生成的表单和传递值的问题 . 我觉得有人必须解决这个问题,或者我错过了一些明显的东西,但我找不到任何提及它的东西 .
例如,我有三个组成部分,父母,孩子,然后是孩子的孩子 . 对于名称,我将使用,formComponent,questionComponent,textBoxComponent . 两个孩子都在使用changeDetection.OnPush .
因此,表单组件通过输入将一些值传递给questionComponent,而一些组件使用异步管道来订阅商店中它们各自的值 .
QuestionComponent动态创建不同的组件,然后将它们放在页面上(如果它们匹配)(这么多类型的组件,但每个questionComponent只处理一个组件) .
一些代码:
@Input() normalValue
@Input() asyncPipedValue
@ViewChild('questionRef', {read: ViewContainerRef}) public questionRef: any;
private textBoxComponent: ComponentFactory<TextBoxComponent>;
ngOnInit() {
let component =
this.questionRef.createComponent(this.checkboxComponent);
component.instance.normalValue = this.normalValue;
component.instance. asyncPipedValue = this. asyncPipedValue;
}
这适用于normalValues的所有实例,但不适用于asyncValues . 我可以在questionComponent的ngOnChanges中确认该值正在更新,但该值未传递给textBoxComponent .
我基本上需要的是异步管道,但不适用于模板 . 我尝试了多种方法来传递asyncValues,我尝试检测asyncPipeValue何时更改,并在textBoxComponent上触发changeDetectionRef.markForChanges(),但只有在我将changeDetectionStrategy更改为normal时才会有效,这有点会影响性能我从使用ngrx获得的收益 .
这似乎太过疏忽而没有解决方案,所以我假设这只是我没有想到的东西 . 有什么想法吗?
3 回答
我做了类似的事情,我从我的Ngrx商店的数据填充表格 . 我的表格不是动态的,所以我不能100%确定这是否也适合你 .
仅使用setter定义输入,然后在窗体/窗体控件上调用patchValue()或setValue() . 您的根组件保持不变,使用异步管道将数据传递到下一个组件 .
patchValue()在AbstractControl类上 . 如果您无法访问问题组件中的那个,则TextBoxComponent可以公开一个类似的方法,可以从QuestionComponent调用,并且实现执行控件的更新 .
但要注意的一件事是,如果您还在表单/控件上订阅valueChanges,则可能需要设置第二个参数,以便valueChanges事件不会立即触发 .
要么
然后在TextBoxComponent中
这种方法运行良好,无需在任何地方保存/更新按钮 .
我相信我已经找到了解决方案(在gitter.com/angular Channels 的帮助下) .
由于值将进入questionComponent可以更改,并触发它的ngOnChanges触发,只要ngOnChanges中有事件,它就需要解析整个事件,并绑定并更改为动态子组件 .
这都是在QuestionComponent中,如果它们已经改变,它会重置组件实例变量 . 到目前为止,最大的问题是孩子的ngOnChanges没有触发,所以这不是一个完整的解决方案 . 我会继续深入研究它 .
以下是我对这个问题的看法,考虑到有限的代码片段 .
首先,提供的示例似乎与
ngrx
没有任何关系 . 在这种情况下,预计ngOnInit
仅运行一次,此时this.asyncPipedValue
值为undefined
. 因此,如果this.checkboxComponent
的this.checkboxComponent
是ChangeDetection.OnPush
,则该值将不会更新 . 我建议阅读有关更改检测和传递异步输入的one excellent article . 该文章还包含有关变更检测的其他资源 . 此外,似乎相同的输入在组件树中传递两次,从我的角度来看这不是一个好的解决方案 .其次,另一种方法是使用
ngrx
然后根本不需要传递任何异步输入 . 特别是,如果两个组件在组件树中没有父子关系,则这种方式很好 . 在这种情况下,一个组件调度将数据放入Store的操作,另一个组件从Store订阅该数据 .希望这有助于或至少提供一些线索 .