模型驱动表单 - IE11 上的输入占位符问题

Posted

技术标签:

【中文标题】模型驱动表单 - IE11 上的输入占位符问题【英文标题】:Model driven forms - input placeholder issue on IE11 【发布时间】:2017-11-10 01:20:08 【问题描述】:

我已将我的应用程序从 Angular 2.x 更新到 Angular 4.0.0。从此时起,我在输入类型文本表单控件中遇到以下问题:


在 IE11 上,当获得焦点时,占位符被移除,表单控件设置为脏,原始设置为 false。 在 Chrome / FF 上,这个问题永远不会发生。

在 IE11 上,输入元素一旦获得焦点就会变脏。例如,与 Chrome 不同,您必须先输入它。

html

<input 
  type="text" 
  class="form-control" 
  id="processName" 
  [(ngModel)]="process.displayName" 
  [disabled]="isProcessLoading"
  #processName="ngModel"
  maxLength="64" 
  pattern="^.*\S.*" 
  name="processName" 
  placeholder="'PROCESS-FORM.name-placeholder' | translate"
  required 
  placeholderRequired 
  [inputBinding]="processName" 
/>

我创建了一个指令,当处于焦点时,将所有错误设置为 null(有效)。

@Directive(
  selector: '[placeholderRequired]'
)
export class PlaceHolderDirective 
  @Input() inputBinding: any = null;

  constructor(private elementRef: ElementRef) 
  

  @HostListener('focus', ['$event'])
  handleFocus(event: any) 
    if (navigator.appVersion && navigator.appVersion.indexOf('.NET') > -1) 
      // IE only
      if (!this.inputBinding._control._value) 
        this.inputBinding.control.setErrors(null);
        setTimeout(() => this.inputBinding.control.setErrors(null),0);
      
    
  

  @HostListener('mousedown', ['$event'])
  handleMouseDown(event: any) 
    if (navigator.appVersion && navigator.appVersion.indexOf('.NET') > -1) 

      if (!this.inputBinding._control._value) 
        this.inputBinding.control.setErrors(null);
        setTimeout(() => this.inputBinding.control.setErrors(null),0);
      
    
  

  @HostListener('blur', ['$event'])
  handleBlur(event: any) 
    if (navigator.appVersion && navigator.appVersion.indexOf('.NET') > -1) 
      if (!this.inputBinding._control._value.trim()) 
        // handle blur event
      
    
  

当用户点击输入字段时,来自 angular 的某处 valueAccessor.onValueChanges(),该字段被标记为脏,使用 control.markAsDirty()。

我也添加了 setTimeout(),但它会在之后执行 执行 markAsDirty() 导致 UI 波动很小(脏 真 -> 脏假)。

这种行为可以用其他方法解决吗? 有没有办法覆盖 onValueChanges() 因为它在内部将字段设置为脏。不需要添加其他库(如 placeholder.js)。

【问题讨论】:

这似乎与一个错误有关。它已经在 angular repo 中报告:github.com/angular/angular/issues/17951 您可以使用修改此答案来解决此问题:***.com/questions/33866824/… 【参考方案1】:

我自定义的原始如下:

ts 文件

iePristine: boolean = true;
pincodeCtrl = <formControl>this.form.get('pincode')
  setPlaceholder() 
    const placeholder = 'Enter Code';
    if (this.pincodeCtrl.value) 
      this.iePristine = false;
    
    if (this.iePristine) 
      this.pincodeCtrl.markAsPristine();
    
    return placeholder;
  

isInvalidControl(control: FormControl) 
    return control.invalid && (control.dirty || control.touched);
  

html文件

<input type="text" [placeholder]="setPlaceholder()" formControlName="pincode"
            [ngClass]="isInvalidControl(pincodeCtrl) ? 'form-control text-center is-invalid' : 'form-control text-center'" />

【讨论】:

以上是关于模型驱动表单 - IE11 上的输入占位符问题的主要内容,如果未能解决你的问题,请参考以下文章

IE浏览器中的占位符文本问题(8-9)

如何将类、id、占位符属性添加到 django 模型表单中的字段

IE 10, 11. 如何防止使用占位符的文本输入触发焦点输入事件?

IE9 RTW 是不是支持输入元素的占位符属性?

将输入字段绑定到模型时不显示 HTML 输入字段占位符

占位符 Internet Explorer 11 未显示