Angular.js: ng-model未设置输入的初始值和位置[类型=范围]

创建于 2014-03-18  ·  35评论  ·  资料来源: angular/angular.js

基本上,使用ng-model将范围输入设置为初始值。 HTML元素的实际值以及范围滑块的位置不正确。 我希望滑块位置和html输入值与model变量同步。

这是一个复制品: http :

已在Windows 8上运行的chrome和firefox上验证

我看到对于input [type = range]还有其他问题,目前尚不清楚它们是否相关。

forms moderate duplicate broken expected use bug

最有用的评论

使用GitHub的新“反应”功能,您不再需要注释“ +1”。 相反,您可以通过单击本期第一条评论右上方的“ +:smile:”,然后选择:+1:(“ +1”)来标记您的兴趣。 这样可以避免向订阅此问题的每个人发送无用的通知。

所有35条评论

Angular 1.2.14仍然存在问题: http :

解决方法是,可以在$ timeout处理程序中设置模型值。

$ timeout没有帮助,问题仍然存在。

@fschwiethttp :

@ Rajat-Chowdhary抱歉,我应该包含一个代码示例,该示例显示$ timeout如何作为变通方法工作: http :

由于无法在$ timeout回调函数初始化之前无法初始化模型值,因此该解决方法确实让人觉得有些麻烦。

看来我找到了问题。
在设置最小值,最大值和步长之前,角度设置值,因此似乎该范围位于错误的位置。 为了解决这个问题,我使用了这个指令

angular.module('angular-range', []).directive('range', function() {
    return {
        replace: true,
        restrict: 'E',
        scope: {
            value: '=ngModel',
            min: '=rangeMin',
            max: '=rangeMax',
            step: '=rangeStep',
        },
        template: '<input type="range"/>',
        link: function(scope, iElement, iAttrs) {
            scope.$watch('min', function() { setValue(); });
            scope.$watch('max', function() { setValue(); });
            scope.$watch('step', function() { setValue(); });
            scope.$watch('value', function() { setValue(); });

            function setValue() {
                if (
                    angular.isDefined(scope.min) &&
                    angular.isDefined(scope.max) &&
                    angular.isDefined(scope.step) &&
                    angular.isDefined(scope.value)
                ) {
                    iElement.attr("min", scope.min);
                    iElement.attr("max", scope.max);
                    iElement.attr("step", scope.step);
                    iElement.val(scope.value); 
                }
            }
            function read() {
                scope.value = iElement.val();
            }

            iElement.on('change', function() {
                scope.$apply(read);
            });
        }
    };
});

这里是没有私有范围的ngRange的新版本:

.module('ngRange', [])
.directive('ngRange', function() {
    return {
        replace: true,
        restrict: 'E',
        require: 'ngModel',
        template: '<input type="range"></input>',
        link: function(scope, element, attrs, ngModel) {
            var ngRangeMin;
            var ngRangeMax;
            var ngRangeStep;
            var value;

            if (!angular.isDefined(attrs.ngRangeMin)) {
                ngRangeMin = 0;
            } else {
                scope.$watch(attrs.ngRangeMin, function(newValue, oldValue, scope) {
                    if (angular.isDefined(newValue)) {
                        ngRangeMin = newValue;
                        setValue();
                    }
                });
            }
            if (!angular.isDefined(attrs.ngRangeMax)) {
                ngRangeMax = 100;
            } else {
                scope.$watch(attrs.ngRangeMax, function(newValue, oldValue, scope) {
                    if (angular.isDefined(newValue)) {
                        ngRangeMax = newValue;
                        setValue();
                    }
                });
            }
            if (!angular.isDefined(attrs.ngRangeStep)) {
                ngRangeStep = 1;
            } else {
                scope.$watch(attrs.ngRangeStep, function(newValue, oldValue, scope) {
                    if (angular.isDefined(newValue)) {
                        ngRangeStep = newValue;
                        setValue();
                    }
                });
            }
            if (!angular.isDefined(ngModel)) {
                value = 50;
            } else {
                scope.$watch(
                    function () {
                        return ngModel.$modelValue;
                    }, 
                    function(newValue, oldValue, scope) {
                        if (angular.isDefined(newValue)) {
                            value = newValue;
                            setValue();
                        }
                    }
                );
            }

            function setValue() {
                if (
                    angular.isDefined(ngRangeMin) &&
                    angular.isDefined(ngRangeMax) &&
                    angular.isDefined(ngRangeStep) &&
                    angular.isDefined(value)
                ) {
                    element.attr("min", ngRangeMin);
                    element.attr("max", ngRangeMax);
                    element.attr("step", ngRangeStep);
                    element.val(value); 
                }
            }

            function read() {
                if (angular.isDefined(ngModel)) {
                    ngModel.$setViewValue(value);
                }
            }

            element.on('change', function() {
                if (angular.isDefined(value) && (value != element.val())) {
                    value = element.val();
                    scope.$apply(read);
                }
            });
        }
    };
});

这仍然是一个问题,对不对?

http://plnkr.co/edit/MAT5KPkXyWblAJ71L8nK?p=preview

是+1

是的,仍然是一个问题。

我在stackoverflow中问过类似的问题,当值超过100时,如何使用AngularJS初始化input [range]的值。 使用1.4.0-beta.build.3791,此错误仍然存​​在。

+1

+1,并且当输入范围与输入数字耦合时,情况变得最糟。

为此问题+1

面临相同的问题:+1

是的-相同的问题+1

这是基本的html5-这是什么状态,有人在从事此工作吗?

考虑这一点: https :
错误:抛出ngModel:numfmt范围滑块
我为此调整了@ ardf69解决方案:

angular.module('common').directive('rangeSlider', [function () {
    return {
        replace: true,
        restrict: 'E',
        require: 'ngModel',
        template: '<input type="range"/>',
        link: function (scope, element, attrs, ngModel) {
            var ngRangeMin;
            var ngRangeMax;
            var ngRangeStep;
            var value;

            function init() {
                if (!angular.isDefined(attrs.ngRangeMin)) {
                    ngRangeMin = 0;
                } else {
                    scope.$watch(attrs.ngRangeMin, function (newValue, oldValue, scope) {
                        if (angular.isDefined(newValue)) {
                            ngRangeMin = newValue;
                            setValue();
                        }
                    });
                }
                if (!angular.isDefined(attrs.ngRangeMax)) {
                    ngRangeMax = 100;
                } else {
                    scope.$watch(attrs.ngRangeMax, function (newValue, oldValue, scope) {
                        if (angular.isDefined(newValue)) {
                            ngRangeMax = newValue;
                            setValue();
                        }
                    });
                }
                if (!angular.isDefined(attrs.ngRangeStep)) {
                    ngRangeStep = 1;
                } else {
                    scope.$watch(attrs.ngRangeStep, function (newValue, oldValue, scope) {
                        if (angular.isDefined(newValue)) {
                            ngRangeStep = newValue;
                            setValue();
                        }
                    });
                }
                if (!angular.isDefined(ngModel)) {
                    value = 50;
                } else {
                    scope.$watch(
                        function () {
                            return ngModel.$modelValue;
                        },
                        function (newValue, oldValue, scope) {
                            if (angular.isDefined(newValue)) {
                                value = newValue;
                                setValue();
                            }
                        }
                    );
                }

                if (!ngModel) {
                    return;
                }
                ngModel.$parsers.push(function (value) {
                    var val = Number(value);
                    if (val !== val) {
                        val = undefined;
                    }
                    return val;
                });
            }

            function setValue() {
                if (
                    angular.isDefined(ngRangeMin) &&
                    angular.isDefined(ngRangeMax) &&
                    angular.isDefined(ngRangeStep) &&
                    angular.isDefined(value)
                    ) {
                    element.attr("min", ngRangeMin);
                    element.attr("max", ngRangeMax);
                    element.attr("step", ngRangeStep);
                    element.val(value);
                }
            }

            function read() {
                if (angular.isDefined(ngModel)) {
                    ngModel.$setViewValue(value);
                }
            }

            element.on('change', function () {
                if (angular.isDefined(value) && (value != element.val())) {
                    value = element.val();
                    scope.$apply(read);
                }
            });

            init();
        }
    };
}
]);

+1,使用ng-if切换[input type = range]时遇到相同的问题

我也遇到了这个问题,并写了一个关于堆栈溢出的问题, “在Angular中,作用域变量_before_ ngModel的bind属性绑定了输入的value 。 该问题包括可重现此问题的可运行代码段。

一些变通办法已发布作为堆栈溢出的答案。 适用于我的情况的一个案例涉及将DOM操作与$inputElement.prop()以设置minmaxstep (所需的任何属性)。 通过在首先设置我的自定义指令的基础<input>value之前执行此DOM操作,可以避免此问题。

解决这个错误的懒惰方法是将最小值/最大值和步长值除以100。所以300变为3.0,依此类推,值降到100以下。然后根据需要乘回。 也许对某人有用。

+1这很烦人。

+1

+1

+1

另一个懒惰的解决方法黑客:

      $timeout(function () {
        angular.element('.slider-input').val(amount);
      });

+1

使用GitHub的新“反应”功能,您不再需要注释“ +1”。 相反,您可以通过单击本期第一条评论右上方的“ +:smile:”,然后选择:+1:(“ +1”)来标记您的兴趣。 这样可以避免向订阅此问题的每个人发送无用的通知。

我已经通过删除ng-model使用ondrag方法解决了我的问题。
检查此http://codepen.io/nagarajumusini/pen/BKpGJz

+1

+1

将ng-init添加到输入可以为我设置初始值

<input type="range" class="slider-years" min="0" max="30" step="1" value="0" data-ng-model="metier.anneeExperience" data-ng-init="metier.anneeExperience ? metier.anneeExperience = metier.anneeExperience : metier.anneeExperience = 0" />

在以下位置找到解决方案:

http://jsfiddle.net/jestho/8dymV/7/

我们正在努力(最终)。 关闭为https://github.com/angular/angular.js/issues/5892的副本

$(document).ready(function(){
angular.element('。yourclasshere')。val(滑块负载的值);
});

此jQuery解决方法有效,因此您可以在页面加载时设置一个值,但是无论滑动控件的值如何,直到触摸它时,它都不会同步。

@davedx也许这是解决问题之前的最佳方法。

<input type="range" min="15" data-ng-init="signup.age=30" value="30" max="85" step="1" name="ageInput" class="form-control input-lg" ng-model="signup.age" oninput="ageOutputId.value = ageInput.value" /> <output name="ageOutputName" id="ageOutputId">30</output>

此页面是否有帮助?
0 / 5 - 0 等级