gpt4 book ai didi

Angular:使用自定义 ControlValueAccessor 测试组件时从不调用 registerOnChange

转载 作者:搜寻专家 更新时间:2023-10-30 21:57:42 26 4
gpt4 key购买 nike

如我所描述in this answer ,我创建了一个自定义 ControlValueAccessor 指令来控制何时触发我的组件的 onChange 事件,并且一切正常,除了当我测试它时, registerOnChange 永远不会被调用,因此,我的测试失败了。

我的指令是这样的:

export const MASK_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MaskDirective),
multi: true
};

@Directive({
selector: "[testMask]",
providers: [MASK_CONTROL_VALUE_ACCESSOR]
})

export class MaskDirective implements ControlValueAccessor {

private onChange;
private nativeElement;

constructor(private element: ElementRef) {
this.nativeElement = this.element.nativeElement;
}

registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
}
setDisabledState(isDisabled: boolean): void {
this.nativeElement.disabled = isDisabled;
}
writeValue(newValue) {
newValue = newValue == null ? "" : newValue;
this.nativeElement.value = newValue;
}
@HostListener("input", ["$event"])
onInput(event: KeyboardEvent) {
/*DO YOUR STUFF HERE*/
// Call onChange to fire the valueChanged listeners
this.onChange(newValue);
}
}

还有我的测试:

describe("Test Custom Directive", () => {
@Component({
template:
`<input type="text" [formControl]=inputFormControl testMask/>`
})
class TestComponent {

_inputFormControl: FormControl;

constructor(private element: ElementRef) {
this._inputFormControl = new FormControl();
}

get inputFormControl() {
return this._inputFormControl;
}
}

let fixture: ComponentFixture<TestComponent>;
let inputField: HTMLInputElement;

const getInput = (fix: ComponentFixture<TestComponent>) => {
const inputDebug = fix.debugElement.query(By.directive(MaskDirective));
return inputDebug.nativeElement as HTMLInputElement;
};

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
MaskDirective
]
});
});
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
inputField = getInput(fixture);
});

it("test", async () => {
//Tests fails because there's no onChange callback
});
}

基于我在 "Never again be confused when implementing ControlValueAccessor in Angular forms" 上阅读的内容我假设只要将 FormControl 添加到我的输入字段就应该触发 setupControl,但事实显然并非如此。我错过了什么?

最佳答案

您需要在 configureTestingModule 声明中导入 FormsModule。

我做了一点不同。通过使用 ReactiveFormsModule 和名为“directiveForm”的指令

@Component({
template: `<form [formGroup]="testForm"><input type="text" formControlName="testControl" directiveForm></form>`
})
class TestComponent {

public testForm: FormGroup;

constructor(private fb: FormBuilder) {

this.testForm = this.fb.group({
testControl: new FormControl()
});
}
}

describe('Directive Test', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
DirectiveForm,
TestComponent
],
imports: [DirectiveFormModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));

这种方式适合我

关于Angular:使用自定义 ControlValueAccessor 测试组件时从不调用 registerOnChange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51795426/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com