Angular 角度应用组件体系结构
我目前正在尝试Angular 7*中应用程序组件的设计。由于没有对它做过很多工作,我发现很难设计一个干净的组件体系结构 这个组件,让我们称之为MainComponent,它接收一个JSON输入,例如Angular 角度应用组件体系结构,angular,Angular,我目前正在尝试Angular 7*中应用程序组件的设计。由于没有对它做过很多工作,我发现很难设计一个干净的组件体系结构 这个组件,让我们称之为MainComponent,它接收一个JSON输入,例如 { "name": "name", "description": "description", "attributes": [ // Rectangle in the image { "attr1": "value", // Editable
{
"name": "name",
"description": "description",
"attributes": [ // Rectangle in the image
{
"attr1": "value", // Editable
"attr2": "value", // Editable
"attr3": "value" // Editable
},
{
"attr1": "value", // Editable
"attr2": "value", // Editable
"attr3": "value" // Editable
},
...
]
}
重要的字段是属性。它的每个元素都将显示为一个单独的区域,我想将其编码为一个新组件
每个属性元素在主元素内变成一个矩形。
属性的每个字段都是可编辑的,因此必须构造FormGroup
但是,保存是全局的,而不是每个子组件。
我需要注意倾听每个组件中修改了哪些值
我考虑过两种解决方案
在主级别上有一个FormGroup,其中包含多个子FormGroup,每个子组件一个。每个子表单组都输入到子组件中。在保存时,我只查看主FormGroup,它已经包含所有更改的值
每个子组件都拥有一个单独的FormGroup。保存时,主组件要求调用每个子组件的方法来检索修改后的值
哪种解决方案最适合于角型?你会怎么做
编辑:我想问的是,如何更好地将JSON输入分发到多个子组件,并在保存时检索编辑的值,这是在上/主级别。我认为解决此类问题的最佳方法是数据共享。我们应该始终建立一种共同的服务。在那里放置一个表单组。并在每个组件中编写方法来更新该表单组的值。最后给出了一种求表单组值的方法。到目前为止,它是在服务中编写共享FormGroup代码的最佳方法
this.lotTwoFormGroup = this.formBuilder.group({
title: ['', Validators.compose([Validators.required])],
description: ['', Validators.compose([Validators.required])],
dutchTitle: [''],
dutchDescription: [''],
frenchTitle: [''],
frenchDescription: ['']
});
这是一个
我用过Formaray。欲了解更多信息,请阅读
首先,让我们创建一个输入组件,并将其称为MyInputComponent
并且,您可以在模板中使用此组件,如下所示
<div *ngFor="let attr of attributes; let i = index">
<my-input></my-input>
<hr />
</div>
export class AppComponent {
myForm = this.fb.group({
array: this.fb.array([])
})
attributes = [
{ 'attr1': 'value1', 'attr2': 'value12'},
{ 'attr1': 'value2', 'attr2': 'value22'},
{ 'attr1': 'value3', 'attr2': 'value32'},
];
constructor(private fb: FormBuilder) {}
ngOnInit() {
const arrayFormControl = this.myForm.get('array') as FormArray;
this.attributes.forEach(attr =>
arrayFormControl.push(this.fb.control(attr)));
}
save() {
console.log(this.myForm.value);
}
}
并将主组件的模板更改为
<div [formGroup]="myForm">
<div formArrayName="array">
<div *ngFor="let attr of attributes; let i = index">
<my-input [formControlName]="i"></my-input>
<hr />
</div>
<button (click)="save()">Save</button>
</div>
</div>
您可以调用共享组件并使用输入属性值创建表单组?编辑:问题是“保存”按钮在父组件上。@MsuArven“共享组件”是什么意思?是的,问题是那个!我认为最好的方法是使用formArray检查这个链接:@BunyaminCoskuner基本上在主组件中,我必须创建一个FormGroup,其中包含一个formArray的FormGroups?你是这么说的吗?因此,答案是选项1仅在主级别管理状态和表单组。此外,您需要使您的输入组件实现ControlValueAccessor,以便您可以在该组件上使用formControlName。非常感谢!有一个问题,在MyInputComponent中有一个值字段,它是非类型化的,因为接口使用任何类型。在这种情况下,它会是一个FormGroup吗?当您链接到它[formControlName]=iOkay时,它将是FormControl。只需阅读arrayFormControl.pushthis.fb.controlattr;这不是形式控制。它是你绑定的任何值。这样做的好处是MyInputComponent不知道如何使用它。您也可以使用ngModel而不是[formControlName]=i。好的!如何验证MyInputComponent中的单个属性?那不是个问题吗?是的,我想是的
@Component({
selector: 'my-input',
template: `
<div>
Attr1: <input type="text" [ngModel]="value.attr1" (ngModelChange)="updateModel($event, 'attr1')" />
</div>
<div>
Attr2: <input type="text" [ngModel]="value.attr2" (ngModelChange)="updateModel($event, 'attr2')" />
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyInputComponent),
multi: true
}
]
})
export class MyInputComponent implements ControlValueAccessor {
value;
onChange;
onTouched;
disabled = false;
updateModel(value, attrName) {
this.value[attrName] = value;
this.onChange(this.value); // now I call onChange method to update the value within form
}
// comes from ControlValueAccessor
writeValue(newValue): void {
this.value = newValue;
}
// comes from ControlValueAccessor
registerOnChange(fn: (rating: number) => void): void {
this.onChange = fn;
}
// comes from ControlValueAccessor
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
// comes from ControlValueAccessor
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
}
<div [formGroup]="myForm">
<div formArrayName="array">
<div *ngFor="let attr of attributes; let i = index">
<my-input [formControlName]="i"></my-input>
<hr />
</div>
<button (click)="save()">Save</button>
</div>
</div>
export class AppComponent {
myForm = this.fb.group({
array: this.fb.array([])
})
attributes = [
{ 'attr1': 'value1', 'attr2': 'value12'},
{ 'attr1': 'value2', 'attr2': 'value22'},
{ 'attr1': 'value3', 'attr2': 'value32'},
];
constructor(private fb: FormBuilder) {}
ngOnInit() {
const arrayFormControl = this.myForm.get('array') as FormArray;
this.attributes.forEach(attr =>
arrayFormControl.push(this.fb.control(attr)));
}
save() {
console.log(this.myForm.value);
}
}