【问题标题】:only Number Directive issues只有数字指令问题
【发布时间】:2018-03-12 12:00:09
【问题描述】:

我已复制粘贴以下指令

.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/20 而不是 0/20)并且不会弹出错误。当我按下提交时,我能够得到我输入的非数字值。

@已编辑

<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端

$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;
               }


        };

它会弹出错误并以红色突出显示字段,请参见图片

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

【问题讨论】:

  • 能否请您也分享一下 HTML,错误消息是从哪里生成的,如果可能的话,还有一个有效的 sn-p。
  • @NarenMurali 我已经更新了问题并提供了更多细节!!

标签: angularjs angularjs-directive angularjs-material


【解决方案1】:

您的指令不会更新 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);
                }
            });
        }
    };
})

【讨论】:

  • @Fetra ,好的,解决了一个问题。我已经更新了问题并提供了更多细节来解决第二个问题。请看。
【解决方案2】:
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" />

【讨论】:

  • 预计会为您的答案提供一些解释,以说明它如何解决问题,请避免仅发布代码答案。
猜你喜欢
  • 1970-01-01
  • 2010-11-15
  • 2015-12-05
  • 2012-01-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 2020-08-12
  • 1970-01-01
相关资源
最近更新 更多