我有一个指令:
@Directive({
selector: 'input[type=file][ngModel], input[type=file][formControlName], input[type=file][formControl]',
host: {
'(change)': 'filesSelected($event.target.files)',
'(blur)': 'onTouched()'
},
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef( () => FileValueAccessor),
multi: true
}]
})
export class FileValueAccessor implements ControlValueAccessor {
onChange = (_) => {};
onTouched = () => {};
fileListComponent: ComponentRef<FileUploadListComponent>;
files: File[] = [];
constructor(
private _renderer: Renderer,
private _elementRef: ElementRef,
private resolver: ComponentFactoryResolver,
private viewContainer: ViewContainerRef) {
const factory = this.resolver.resolveComponentFactory(FileUploadListComponent);
this.fileListComponent = this.viewContainer.createComponent(factory);
this.fileListComponent.instance.removeFileCb = (file) => this.removeFile(file);
}
removeFile(file) {
this.files = this.files.filter((f: File): Boolean => f !== file);
this.filesUpdated();
}
writeValue(value): void {
}
filesSelected(files: FileList) {
for(let i in files) {
const file = files[i];
if (isFile(file) && this.files.findIndex((f: File) => f.name === file.name && f.size === file.size) === -1) {
this.files.push(file);
}
}
this.filesUpdated();
}
filesUpdated() {
this.fileListComponent.instance.files = this.files;
this.onChange(this.files);
}
registerOnChange(fn: (_: FileList) => void): void { this.onChange = fn; }
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
setDisabledState(isDisabled: boolean): void {
this._renderer.setElementProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
}
}
我正试图这样测试:
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should update files', async(inject([FileValueAccessor, ViewContainerRef], (fileAccesser: FileValueAccessor, viewContainer: ViewContainerRef) => {
const files = Array(8).fill(getFile(randomValidFileName()))
fileAccesser.files = files;
fileAccesser.filesUpdated();
fixture.detectChanges();
expect(fixture.elementRef.nativeElement.querySelectorAll('app-file-upload-list-item').length).toBe(8);
})))
但我得到了
错误:未实现this.fileListComponent = this.viewContainer.createComponent(工厂);来自指令
值得注意的是,指令构造函数执行了两次,这是第二次发生错误。