为什么Pipe在Angular2中无法正常工作?

时间:2016-04-06 07:44:57

标签: javascript angular

任务很简单,输入只需要输入一定数量以下的数字。我这样做了:

export class MaxNumber implements PipeTransform{
   transform(value, [maxNumber]) {
        value = value.replace(/[^\d]+/g,'');
        value = value > maxNumber?maxNumber:value;
        return value;
    }
}

然后在模板中调用类似:

<input type="text" [ngModel]="obj.count | maxNumber:1000" (ngModelChange)="obj.count=$event" />

但它的作用很奇怪click

我可能误解了一些事情。如果有人能解释这种行为,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

我认为你需要一个自定义值访问器。这样,您可以在ngModel中设置之前检查该值。这样,obj.count不会高于1000。

以下是一个示例实现:

const CUSTOM_VALUE_ACCESSOR = new Provider(
    NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => MaxNumberAccessor), multi: true});

@Directive({
  selector: 'input',
  host: {'(input)': 'customOnChange($event.target.value)'},
  providers: [ CUSTOM_VALUE_ACCESSOR ]
})
export class MaxNumberAccessor implements ControlValueAccessor {
  onChange = (_) => {};
  onTouched = () => {};

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

  writeValue(value: any): void {
    var normalizedValue = (value == null) ? '' : value;
    this._renderer.setElementProperty(this._elementRef.nativeElement,  'value', normalizedValue);
  }

  customOnChange(val) {
    var maxNumber = 1000;
    val = val.replace(/[^\d]+/g,'');
    val = val > maxNumber?maxNumber:val;
    this.onChange(val);
  }

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

组件无需使用它,只需将此指令设置为directives属性:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      Number: <input type="text" [(ngModel)]="obj.count" />
      <p>Actual model value: {{obj.count}}</p>
    </div>
  `,
  directives: [MaxNumberAccessor]
})
export class App {
  (...)
}

对应的plunkr:https://plnkr.co/edit/7e87xZoEHnnm82OYP84o?p=preview