只有数字指令问题

时间:2017-10-01 00:16:34

标签: angularjs angularjs-directive angularjs-material

我已复制粘贴以下指令

.directive("onlyNumber", function () {
    return {
        restrict: "A",
        link: function (scope, element, attr, ngModel) {
            element.bind('input', function () {
                var position = this.selectionStart - 1;

                //remove all but number and .
                var fixed = this.value.replace(/[^0-9\.]/g, '');  
                if (fixed.charAt(0) === '.')                  //can't start with .
                    fixed = fixed.slice(1);

                var pos = fixed.indexOf(".") + 1;
                if (pos >= 0)               //avoid more than one .
                    fixed = fixed.substr(0, pos) + fixed.slice(pos).replace('.', '');

                if (this.value !== fixed) {
                    this.value = fixed;
                    this.selectionStart = position;
                    this.selectionEnd = position;
                }
            });
        }
    };
})

问题是它只在我键入时才起作用,如果我填充该值,则会显示错误所需的消息。

第二个问题是,当我输入非数字键时,它会删除该值,但长度计数器会增加1(即1/20而不是0/20),并且不会弹出错误。当我按提交时,我能够获得我输入的非数字值。

@Edited

<ng-form name="nOtherFacilityForm" novalidate isolate-form flex="100" layout-padding layout layout-wrap>

                    <h2 class="md-title">Other Facilities</h2>
                    <div flex="100" class="animate-slide-up md-whiteframe-1dp white-bg" layout-padding layout layout-wrap>

                        <div flex="100" flex-gt-sm="25">
                            <md-input-container class="md-block">
                                <label>Almirah</label>
                                <input type="text" only-number  name="almirah" ng-model="LibraryEquipDetails.almirah" md-maxlength="20" maxlength="20"  required />
                                <div ng-messages="nOtherFacilityForm.almirah.$error">
                                    <div ng-message="required">Almirah is required.
                                    </div>
                                </div>
                            </md-input-container>
                        </div>
</ng-form>

和js side

$scope.saveInfo = function () {



            if($scope.nOtherFacilityForm.$invalid){
                angular.forEach($scope.nOtherFacilityForm.$error, function (field) {
                  angular.forEach(field, function(errorField){
                    errorField.$setTouched();
                  })
                });
            toastr.error("Please Fill All Mandatory Fields", "Alert!");
            return;
               }


        };

弹出错误并突出显示红色字段,请参阅图像 ERROR

当我再次输入时,一切都很好!!

2 个答案:

答案 0 :(得分:2)

您的指令不会更新ngModel,只是更新值。

更新您的ngModel使用:

ngModel.$setViewValue(fixed);

但您需要添加:require: "?ngModel"

.directive("onlyNumber", function () {
    return {
        restrict: "A",
        require: "?ngModel",
        link: function (scope, element, attr, ngModel) {
            element.bind('input', function () {
                var position = this.selectionStart - 1;

                //remove all but number and .
                var fixed = this.value.replace(/[^0-9\.]/g, '');  
                if (fixed.charAt(0) === '.')                  //can't start with .
                    fixed = fixed.slice(1);

                var pos = fixed.indexOf(".") + 1;
                if (pos >= 0)               //avoid more than one .
                    fixed = fixed.substr(0, pos) + fixed.slice(pos).replace('.', '');

                if (this.value !== fixed) {
                    this.value = fixed;
                    this.selectionStart = position;
                    this.selectionEnd = position;
                    ngModel.$setViewValue(fixed);
                }
            });
        }
    };
})

答案 1 :(得分:0)

import { Directive, ElementRef, HostListener, Input } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
    selector: 'input[numbersOnly]'
})
export class NumberDirective {

    constructor(private _el: ElementRef) { }

    @HostListener('input', ['$event']) onInputChange(event) {
        const initalValue = this._el.nativeElement.value;
        this._el.nativeElement.value = initalValue.replace(/[^0-9]*/g, '');
        if (initalValue !== this._el.nativeElement.value) {
            event.stopPropagation();
        }
    }

}

并实现此组件

<input type="text" class="form-control" name="zipcode" formControlName="zipcode" numbersOnly maxlength="5" />