8

我在使用 AngularJS 绑定数值时遇到问题。

我在 JSFiddle 上放了一个简化的例子:http: //jsfiddle.net/treerock/ZvdXp/

<div ng-controller="MyCont" ng-app>  
    <input type="number" min="0" max="50" value="{{value}}" ng-model="value" />    
    <input type="text" value="{{value}}" ng-model="value" />
    <input type="range" min="0" max="50" value="{{value}}" ng-model="value" />    
    {{value}}   
</div>

这应该是三种不同类型的输入字段,如果您更新一种,那么所有值都应该更新。除了数字输入之外,这是有效的。例如,如果我在第一个数字框中输入 20,它会更新所有其他值实例。但如果我更新文本或范围输入,数字输入变为空白。

我想知道问题是否与数字在字段之间的表示/转换方式有关。例如,数字输入是浮点数,文本输入是字符串?

4

5 回答 5

11

你是对的,它与字符串与数字类型有关。我用一个$scope.watch语句来修复它:http: //jsfiddle.net/ZvdXp/6/

于 2013-10-16T13:49:26.563 回答
5

您也可以使用指令解决此问题。我创建了一个指令来强制绑定到数字字段的输入为数字。

html:

myApp.directive('numericbinding', function () {
        return {
            restrict: 'A',
            require: 'ngModel',
            scope: {
                model: '=ngModel',
            },                
           link: function (scope, element, attrs, ngModelCtrl) {
               if (scope.model && typeof scope.model == 'string') {
                   scope.model = parseInt(scope.model);
               }                  
            }
        };
});

您可以将其添加到您的数字字段中,如下所示:

<input data-ng-model="stringnumber" numericbinding type="number"/>    

完整示例:http: //jsfiddle.net/tdjager/cMYQ3/1/

于 2013-12-12T09:15:45.907 回答
5

我已经扩展了蒂姆的答案,以在用户更新控制值后使其更正数据类型。

myApp.directive('numericbinding', function () {
    return {
        restrict: 'A',
        require: 'ngModel',
        scope: {
            model: '=ngModel',
        },                
        link: function (scope, element, attrs, ngModelCtrl) {
           if (scope.model && typeof scope.model == 'string') {
               scope.model = parseInt(scope.model);
           } 
           scope.$watch('model', function(val, old) {
               if (typeof val == 'string') {
                   scope.model = parseInt(val);
               }
           });                 
        }
    };
});
于 2014-12-26T08:03:46.013 回答
4

如果您希望在模型中保存数值,您可以使用指令将文本输入生成的字符串和范围输入通过角度解析器转换为数值,如下所示:

myApp.directive('numericsaving', function () {
    return {
        restrict: 'A',
        require: '?ngModel',
        scope: {
            model: '=ngModel'
        },
        link: function (scope, element, attrs, ngModelCtrl) {
            if (!ngModelCtrl) {
                return;
            }
            ngModelCtrl.$parsers.push(function (value) {
                if (!value || value==='' || isNaN(parseInt(value)) || parseInt(value)!==value) {
                    value=0;
                }
                return parseInt(value);
            });
        }
    };
});

在 HTML 中,保持数字输入不变,并以这种方式在其他输入中添加指令:

<input type="number" min="0" max="50" value="{{value}}" ng-model="value" />
<input type="range" min="0" max="50" value="{{value}}" ng-model="value" numericsaving/>
<input type="text" value="{{value}}" ng-model="value" numericsaving/>

角度解析器将在将字符串输入保存到模型之前将其转换为数值,因此数值输入将自动工作。 这里是完整的小提琴

此外,如果用户在文本输入中插入字母或任何奇怪的字符,它们将不会保存在模型中,从而防止在您的应用程序的单一事实来源中出现无效值。只有文本开头的“+”和“-”字符会被正确解析,所以即使是负值也是允许的。我希望这有帮助!:)

于 2015-02-05T18:43:46.857 回答
1

TypeScript 版本启发了 ainos984,为了后代

     export class ngIntegerDirective implements ng.IDirective {

        static directiveKey: string = 'ngInteger';

        require: string = 'ngModel';

        link = (scope, ele, attr, ctrl: ng.INgModelController) => {
            ctrl.$parsers.unshift(function (viewValue) {
                let result: number = parseInt(viewValue,10);
                if (isNaN(result)) {
                    result = 0;
                }
                return result;
            });
        }

        public static Factory(): ng.IDirectiveFactory {
            const directive = () => new ngIntegerDirective();
            directive.$inject = []; //injecter les dépendances ici
            return directive;
        }
    }
于 2016-03-25T09:29:41.800 回答