kittencup / angular2-ama-cn

angular2 随便问
692 stars 101 forks source link

如何在Directive中更新NgModel? #215

Closed iliuyt closed 7 years ago

iliuyt commented 7 years ago

写了一个指令来限制只能输入数字,并且去除输入框签名的0,DOM更新没有问题,但是ngmodel绑定的数据不同步,会一些偏差,在git上找了很多在Directive获取NgModel更新VIEW的代码,但是都不能用,请大神帮忙看下。

import { Directive, Optional, ElementRef } from '@angular/core';
import { NgModel } from '@angular/common';

// 自定义指令
@Directive({
  selector: 'input[number]',
  host: {
    '(keyup)': 'onKeyUp($event)'
  },
  inputs: ['maxValue'],
})

export class NumberInput {
  private el: HTMLInputElement | HTMLTextAreaElement;
  private ngModel: NgModel;

  constructor(el: ElementRef, @Optional() ngModel: NgModel) {
    this.el = el.nativeElement;
    // 这里获取ngmodel什么都没有,关键就在这里如何获取到ngmoel,
    // 在这里正确的获取到ngmodel,我在onKeyPress就可以更新viewToModelUpdate
    this.ngModel = ngModel;
  }

  onKeyUp() {
    // 为了测试 我直接在这里更改为+1,可以很清楚的看到,数据不同步
    this.el.value = this.el.value.trim() + "1";
    if (this.ngModel) {
      this.ngModel.viewToModelUpdate(this.el.value);
    }
  }
}
import { Component } from '@angular/core';
import { NumberInput } from '../../theme/directives';

@Component({
  selector: 'app',
  template: 
  <input [(ngModel)]="data" number  />
  <label>   {{ data }}</label>
 ,
  directives: [NumberInput],
})
export class App{
  data = "0";
}
iliuyt commented 7 years ago

解决了,ngModel引用错了,附上代码

import { Directive } from '@angular/core';
import { NgModel }   from '@angular/forms';

// 自定义指令
@Directive({
  selector: 'input[number]',
  host: {
    '(keypress)': 'onkeypress($event)',
    '(keyup)': 'onkeyup($event)'
  },
  inputs: ['maxValue'],
})

export class NumberInput {
  maxValue: number;

  constructor(public control: NgModel) {
  }

  onkeyup(event) {
    let input = event.target;
    if (input.value == "") {
      input.value = 0;
      this.control.viewToModelUpdate(0);
    }
    let newValue = parseInt(input.value);
    if (newValue > this.maxValue) {
      input.value = this.maxValue;
      this.control.viewToModelUpdate(this.maxValue);
    }
    else
    {
      input.value = newValue;
      this.control.viewToModelUpdate(newValue);
    }

  }

  onkeypress(event) {
    // 判断是否为数字
    let inputStr = String.fromCharCode(event.keyCode);
    if (!parseInt(inputStr)) {
      return false;
    }
  }
}