是否有可能获得formControl的原生元素?

fed*_*lov 30 angular2-forms angular

我有Angular2 反应型.我创建了formControls并将其分配给输入字段[formControl]=....据我所知,它创造了nativeElement <-> formControl链接.

我的问题:是有可能得到nativeElementformControl?我想做点什么myFormControl.nativeElement.focus()

baH*_*aHI 10

下面的代码不适用于纯ngModel绑定,所以我做了很多实验.最新的,也由Maximillian Schwarzmuller证实应该是:

@Directive({
    selector: '[ngModel]', // or 'input, select, textarea' - but then your controls won't be handled and also checking for undefined would be necessary
})
export class NativeElementInjectorDirective {
    constructor(private el: ElementRef, private control : NgControl) {
        (<any>control.control).nativeElement = el.nativeElement;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果在主模块中提供并导出此伪指令,它将为所有FormControl附加自定义nativeElement属性.

遗憾的是它不是开箱即用的......


Kir*_*ill 8

Added minor fix to baHI answer(moved logic to OnInit). Error mentioned in comments is probably connected to changes in forms. This answer is for "@angular/forms": "~7.1.0",

    @Directive({
      selector: '[ngModel]'
    })
    export class NativeElementInjectorDirective implements OnInit {
        constructor (private el: ElementRef, private control : NgControl) {}

        ngOnInit(){
          (this.control.control as any).nativeElement = this.el.nativeElement;
        }
    }
Run Code Online (Sandbox Code Playgroud)


yur*_*zui 6

我可以分享一个糟糕的解决方案,但是它对我有用。

在反应形式中,我们可以使用

1)FormControlDirective

ts

myControl = new FormControl('')
Run Code Online (Sandbox Code Playgroud)

模板

<input type="text" [formControl]="myControl">
Run Code Online (Sandbox Code Playgroud)

要么

2)FormControlName

ts

myForm: FormGroup;

constructor(private fb: FormBuilder) {}

ngOnInit() {
  this.myForm = this.fb.group({
    foo: ''
  });
}
Run Code Online (Sandbox Code Playgroud)

模板

<form [formGroup]="myForm">
  <input type="text" formControlName="foo">
</form>
Run Code Online (Sandbox Code Playgroud)

因此,对于这些指令,我可以编写一些补丁,例如

1)FormControlDirective

const originFormControlNgOnChanges = FormControlDirective.prototype.ngOnChanges;
FormControlDirective.prototype.ngOnChanges = function() {
  this.form.nativeElement = this.valueAccessor._elementRef.nativeElement;
  return originFormControlNgOnChanges.apply(this, arguments);
};
Run Code Online (Sandbox Code Playgroud)

2)FormControlName

const originFormControlNameNgOnChanges = FormControlName.prototype.ngOnChanges;
FormControlName.prototype.ngOnChanges = function() {
  const result =  originFormControlNameNgOnChanges.apply(this, arguments);
  this.control.nativeElement = this.valueAccessor._elementRef.nativeElement;
  return result;
};
Run Code Online (Sandbox Code Playgroud)

之后,我们可以轻松访问具有FormControl实例的本机元素

1)FormControlDirective

focusToFormControl() {
  (<any>this.myControl).nativeElement.focus();
}
Run Code Online (Sandbox Code Playgroud)

2)FormControlName

focusToFormControlName(name) {
  (<any>this.myForm.get(name)).nativeElement.focus();
}
Run Code Online (Sandbox Code Playgroud)

柱塞示例