簡體   English   中英

Angular 2輸入,管道未更新視圖(更改檢測不起作用)

[英]Angular 2 input with pipe not updating view (change detection not working)

我創建了一個適用於文本輸入的簡單管道。 正則表達式有效-但有些奇怪。 控制台日志正確顯示了新值(已刪除非字母數字),但在瀏覽器中,輸入字段將不會更新,直到我鍵入好字符為止。 因此,鍵入“ 123 !!!! A”將顯示感嘆號,直到鍵入A,然后它們就會消失。 為什么?

我使用這樣的管道:

<input type="text" class="form-control" [ngModel]="name | inputFormat" (ngModelChange)="name=$event">

管道是

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'inputFormat'
})
export class InputFormatPipe implements PipeTransform {

    transform(value: any): any {
    value = value.replace(/[^a-z0-9]/gi, ''); 
    console.log('new value: '+value);
    return value;
  }

}

我懷疑更改檢測無法正常工作-但不確定如何解決此問題。

好的,這是一個示例,說明如何在應由設計處理的地方處理用戶輸入。

測試輸入指令

import { Directive, ElementRef, Renderer2, forwardRef, HostListener } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

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

@Directive({
  selector: 'input[appTestInput]',
  providers: [TEST_VALUE_ACCESSOR]
})
export class TestInputDirective implements ControlValueAccessor {

  onChange = (_: any) => { };
  onTouched = () => { };

  constructor(private _renderer: Renderer2, private _elementRef: ElementRef) { }

  // this gets called when the value gets changed from the code outside
  writeValue(value: any): void {
    const normalizedValue = value == null ? '' : value;
    this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  }

  registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
  registerOnTouched(fn: () => void): void { this.onTouched = fn; }

  setDisabledState(isDisabled: boolean): void {
    this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  }

  // just as an example - let's make this field accept only numbers
  @HostListener('keydown', ['$event'])
  _handleKeyDown($event: KeyboardEvent): void {
    if (($event.keyCode < 48 || $event.keyCode > 57) && $event.keyCode !== 8) {
      // not number or backspace, killing event
      $event.preventDefault();
      $event.stopPropagation();
    }
  }

  @HostListener('input', ['$event'])
  _handleInput($event: KeyboardEvent): void {
    // this is what we should call to inform others that our value has changed
    this.onChange((<any>$event.target).value);
  }
}

只需將此指令聲明添加到您的模塊中:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { TestInputDirective } from './test-input.directive';

@NgModule({
  declarations: [
    AppComponent,
    TestInputDirective // <-- you'll need this
  ],
  imports: [
    BrowserModule,
    FormsModule        // <-- and this
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

然后您可以在模板中使用它,如下所示:

app.component.html

<input type="text" appTestInput [(ngModel)]="name">
<div>{{name}}</div>

確實,這比使用管道的代碼要多一些,但這是處理用戶輸入的正確方法,尤其是當應該以某種方式對其進行預處理時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM