我的组件中有一个大对象,对象中的属性被绑定到模板中的各种组件和输入:
constructor() {
this.data = {
identifier: null,
isRequired: true,
title: 'Untitled',
type: this.fileTypes[0].name,
description: '',
//more code here
}
<app-text-input [(model)]="data.title" label="Title" type="text" variant="white">
由于data
中的所有属性都与各种输入元素绑定,因此对象中的值保持更新。该组件是另一个组件的子组件。
当在父节点上发生某些事件(例如按钮单击)时,父节点需要访问data
对象。我该如何做到这一点?我知道有@Ouptuts
,但事件发生在父母身上,而不是孩子身上。此外,我现在不使用任何FormControl类,我需要实现这一点吗?
有两种方法可以做到。
1。使用BehaviorSubject
当使用响应式表单而不是ngModel
:
时,这将是最好的子组件:
@Input()
data: BehaviorSubject<T>;
form = new FormGroup({
title: new FormControl()
});
ngOnInit() {
this.form.valueChanges.subscribe(formData => {
this.data.next({
...this.data.value,
...formData
});
});
}
<div [formGroup]="form">
<input [formControlName]="title">
</div>
父组件:<child [data]="data"></child>
data: BehaviorSubject<T>;
buttonClicked() {
// use this.data.value
}
2。使用双向绑定。
这仍然使用ngModel
,但需要您自定义在表单元素上使用的双向绑定来触发更新:
子组件:
@Input()
data: T;
@Output()
dataChange: EventEmitter<T>;
<input [model]="data.title" (modelChange)="data.title = $event; dataChange.next(data)">
父组件:<child [(data)]="data"></child>
data: T;
buttonClicked() {
// use this.data
}
你也可以混合&在ngModel上使用双向数据绑定,如2所示。,但将BehaviorSubject
从父级传递给子级,如1。
编辑:这是通过事件发射器的方式,当数据被更改或发出时,您需要在子组件中订阅它,更新的值将显示在子组件或任何其他组件中。
事件发射器Stackblitz
共享服务
SharedService
subject: Subject<Object>;
Parent-Component
constructor(DataService: DataService)
this.DataService.event.next(data);
Child-Component
constructor(DataService: DataService)
this.DataService.event.subscribe((data)=>{
//emitted event with updated data
});
每当父类使用next方法发出时,您都可以接收到数据在子组件或其他组件中并对其起作用。