我有一个动态输入组件,该组件可以正常运行,但在尝试进行单元测试时却遇到了麻烦。问题似乎围绕着使用:
this.form = <FormGroup>this.controlContainer.control;
基本上,它使用的是放置在其父级中的表单组,我不想每次都传递表单组,因为在任何给定的页面上可能有数百个表单组。
无论我尝试什么,都会遇到上述(标题中)错误。
这是我的测试规范(由于我一直在尝试几种不走运的方法,因此可能有不必要的代码:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {DynamicInputsComponent} from './dynamic-inputs.component';
import {FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators} from "@angular/forms";
import {NgbModule} from "@ng-bootstrap/ng-bootstrap";
fdescribe('DynamicInputsComponent', () => {
let component: DynamicInputsComponent;
let fixture: ComponentFixture<DynamicInputsComponent>;
const controls: any = {
testControl: new FormControl({value: '', disabled: false}, []),
};
let thisForm = new FormGroup(controls);
const formBuilder: FormBuilder = new FormBuilder();
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DynamicInputsComponent],
imports: [ReactiveFormsModule, FormsModule, NgbModule],
providers: [
{provide: FormBuilder, useValue: formBuilder}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DynamicInputsComponent);
component = fixture.componentInstance;
component.form = formBuilder.group({
chain: ['chain', Validators.required],
ip: [
'',
Validators.required
],
action: ['action', Validators.required]
});
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
这是我的组成部分:
import {Component, Input, OnInit} from '@angular/core';
import {ControlContainer, FormControl, FormGroup} from '@angular/forms';
@Component({
selector: 'app-dynamic-input',
templateUrl: './dynamic-inputs.component.html',
styleUrls: ['./dynamic-inputs.component.css']
})
export class DynamicInputsComponent implements OnInit {
public form: FormGroup;
@Input() fromData: FormControl;
@Input() controlName: string; // formControlName for this element
@Input() value: any; // Preset Value
@Input() type: string = 'text'; // Preset Value
@Input() id: string; // Add an id to the field, if no id provided controlName is used
@Input() label: string = ''; // Label for element (all elements should have a label)
@Input() editable: boolean = true; // Is the field currently editable or readonly
@Input() required: boolean = false; // Is the field required
@Input() locked: boolean = false; // if state = locked the lock icon shows up next to label
@Input() labelColumnSize: string = 'col-lg-4'; // Column size for label
@Input() inputColumnSize: string = 'col-lg-4'; // Column size for input
@Input() maxlength: number; // Maximum number of characters
@Input() pattern: string; // Regex pattern of allowed field content
@Input() alt: string = 'Please input ' + this.label; // Alternative text for screen readers
@Input() placeholder: string = ''; // Placeholder text shown before user input
constructor(private controlContainer: ControlContainer) {}
ngOnInit() {
// Assign this.form to the FormGroup of it's parent
this.form = <FormGroup>this.controlContainer.control;
if(this.controlName) {
if(this.form.get(this.controlName).value && Object.keys(this.form.get(this.controlName).value).length !== 0 ) {
this.value = this.form.get(this.controlName).value;
} else {
this.form
.get(this.controlName)
.valueChanges
.subscribe(next => {
this.value = next;
});
}
} else {
this.controlName = '';
}
}
}