如何从子组件获取输入以注册我的表单?
How can I get inputs from a child component to register with my form?
文本形式的问题
当我将包装在组件中的输入添加到我的 angular 表单时,表单不会将该输入作为属于它的控件。这意味着例如NgForm.valid
不可靠,因为它不包含从组件添加的输入。
是什么阻止了这种情况,我该怎么办?
问题代码:
为什么以下测试会失败,我该怎么办?
import { Component, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, NgForm } from '@angular/forms';
@Component({
selector: 'test-input',
template: `<input name="inComponent" ngModel="dummy" required>`
})
class TestInputComponent {
}
@Component({
template: `<form><input name="inForm" ngModel="dummy"><test-input></test-input></form>`
})
class TestFormComponent {
@ViewChild(NgForm)
form: NgForm;
}
fdescribe('Input in Form', () => {
let component: TestFormComponent;
let fixture: ComponentFixture<TestFormComponent>;
beforeEach(async (() => {
TestBed.configureTestingModule({
declarations: [TestFormComponent, TestInputComponent],
imports: [FormsModule]
})
.compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(TestFormComponent);
component = fixture.componentInstance;
await fixture.whenStable();
fixture.detectChanges();
});
it('form has all inputs', () => {
expect(Object.keys(component.form.controls).sort()).toEqual(['inComponent', 'inForm']);
});
});
您需要使用 TestInputComponent 创建自定义表单控件。这是大约三年前的指南 - 天哪,但奇迹般地它几乎起作用了:
https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
除了 useValue
不能与内联匿名函数一起使用外,您必须声明并导出 accessor/validator。或者改为走 useExisting
路线。
在你的 TestInputComponent
上使用 viewProviders
,所以它告诉 angular 你希望这个组件使用现有的 NgForm
@Component({
selector: 'test-input',
template: `<input name="inComponent" ngModel="dummy" required>`,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm }]
})
export class TestInputComponent implements OnInit {}
Stackblitz:https://stackblitz.com/edit/angular-testing-kgwsca
文本形式的问题
当我将包装在组件中的输入添加到我的 angular 表单时,表单不会将该输入作为属于它的控件。这意味着例如NgForm.valid
不可靠,因为它不包含从组件添加的输入。
是什么阻止了这种情况,我该怎么办?
问题代码:
为什么以下测试会失败,我该怎么办?
import { Component, ViewChild } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, NgForm } from '@angular/forms';
@Component({
selector: 'test-input',
template: `<input name="inComponent" ngModel="dummy" required>`
})
class TestInputComponent {
}
@Component({
template: `<form><input name="inForm" ngModel="dummy"><test-input></test-input></form>`
})
class TestFormComponent {
@ViewChild(NgForm)
form: NgForm;
}
fdescribe('Input in Form', () => {
let component: TestFormComponent;
let fixture: ComponentFixture<TestFormComponent>;
beforeEach(async (() => {
TestBed.configureTestingModule({
declarations: [TestFormComponent, TestInputComponent],
imports: [FormsModule]
})
.compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(TestFormComponent);
component = fixture.componentInstance;
await fixture.whenStable();
fixture.detectChanges();
});
it('form has all inputs', () => {
expect(Object.keys(component.form.controls).sort()).toEqual(['inComponent', 'inForm']);
});
});
您需要使用 TestInputComponent 创建自定义表单控件。这是大约三年前的指南 - 天哪,但奇迹般地它几乎起作用了: https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
除了 useValue
不能与内联匿名函数一起使用外,您必须声明并导出 accessor/validator。或者改为走 useExisting
路线。
在你的 TestInputComponent
上使用 viewProviders
,所以它告诉 angular 你希望这个组件使用现有的 NgForm
@Component({
selector: 'test-input',
template: `<input name="inComponent" ngModel="dummy" required>`,
viewProviders: [ { provide: ControlContainer, useExisting: NgForm }]
})
export class TestInputComponent implements OnInit {}
Stackblitz:https://stackblitz.com/edit/angular-testing-kgwsca