Angular.js: لا يحدد ng-model القيمة الأولية وموضع الإدخال [النوع = النطاق]

تم إنشاؤها على ١٨ مارس ٢٠١٤  ·  35تعليقات  ·  مصدر: angular/angular.js

بشكل أساسي ، يتم إعداد إدخال النطاق بقيمة أولية باستخدام نموذج ng. القيمة الفعلية لعنصر HTML وموضع شريط تمرير النطاق غير صحيحين. أتوقع أن يكون موضع شريط التمرير وقيمة إدخال html متزامنين مع متغير النموذج.

هنا نسخة: http://jsfiddle.net/fschwiet/HVp2J/

تم التحقق منه على Chrome و Firefox يعملان على Windows 8.

أرى أن هناك مشكلات أخرى مفتوحة للإدخال [type = range] ، وليس من الواضح أنها مرتبطة.

forms moderate duplicate broken expected use bug

التعليق الأكثر فائدة

مع ميزة ردود الفعل الجديدة في GitHub ، لم تعد بحاجة إلى التعليق "+1". بدلاً من ذلك ، يمكنك تحديد اهتمامك بالنقر فوق "+: ابتسامة:" في الجزء العلوي الأيسر من التعليق الأول في هذا العدد ، ثم اختيار: +1: ("+1"). يؤدي هذا إلى تجنب إرسال إشعار عديم الفائدة إلى كل شخص مشترك في هذه المشكلة.

ال 35 كومينتر

لا تزال هذه مشكلة في Angular 1.2.14: http://jsfiddle.net/HVp2J/7/

كحل بديل ، يمكن للمرء تعيين قيمة النموذج داخل معالج مهلة $.

$ timeout لا يساعد ، تبقى المشكلة.

fschwiet : http://jsfiddle.net/HVp2J/9/

@ Rajat-Chowdhary عذرًا ، كان يجب أن أدرج نموذجًا لرمز يوضح كيف يمكن أن يعمل $ timeout كحل بديل :

يبدو الحل البديل مشبوهًا نظرًا لأنه لا يمكن تهيئة قيمة النموذج حتى يعمل رد نداء مهلة $ للحل البديل.

يبدو أنني وجدت المشكلة.
يحدد Angular القيمة قبل تعيين min و max و step لذا يبدو أن النطاق في الموضع الخاطئ. لحل المشكلة ، استخدمت هذا التوجيه

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 كيفية تهيئة قيمة المدخلات [النطاق] باستخدام AngularJS عندما تكون القيمة أعلى من 100 . باستخدام 1.4.0-beta.build.3791 ، لا يزال هذا الخطأ موجودًا.

+1

+1 ، وأصبح أسوأ عندما يقترن نطاق الإدخال برقم إدخال.

+1 لهذه المشكلة

تواجه نفس المشكلة: +1

نعم - نفس المشكلة +1

هذا هو html5 الأساسي - ما هو الوضع في هذا ، هل يعمل أحد على هذا؟

مع الأخذ في الاعتبار هذا: https://github.com/danielcrisp/angular-rangeslider/issues/51
حيث الخطأ: ngModel: يتم طرح منزلق النطاق
قمت بتعديل حل

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

واجهت أيضًا هذه المشكلة ، وكتبت سؤال Stack Overflow حولها ، "In Angular ، ربط السمة من متغير النطاق _before_ ngModel يربط الإدخال value " . يتضمن السؤال مقتطف رمز قابل للتشغيل يعيد إنتاج هذه المشكلة.

تم نشر بعض الحلول كإجابات على Stack Overflow. تتضمن الحالة التي تنطبق على حالتي استخدام معالجة DOM مع $inputElement.prop() لتعيين قيم min ، max ، و step (أي السمات المطلوبة). من خلال القيام بمعالجة DOM هذه قبل تعيين <input> 's value لتوجيهي المخصص لأول مرة ، أتجنب المشكلة.

كانت الطريقة البطيئة لمعالجة هذا الخطأ هي قسمة قيم min / max والخطوة على 100. لذا يصبح 300 3.0 ، وما إلى ذلك ، وتنخفض القيم إلى أقل من 100. ثم أضرب الأشياء مرة أخرى حسب الحاجة. ربما يكون مفيدًا لشخص ما.

+1 هذا مزعج للغاية.

+1

+1

+1

اختراق حل آخر كسول:

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

+1

مع ميزة ردود الفعل الجديدة في GitHub ، لم تعد بحاجة إلى التعليق "+1". بدلاً من ذلك ، يمكنك تحديد اهتمامك بالنقر فوق "+: ابتسامة:" في الجزء العلوي الأيسر من التعليق الأول في هذا العدد ، ثم اختيار: +1: ("+1"). يؤدي هذا إلى تجنب إرسال إشعار عديم الفائدة إلى كل شخص مشترك في هذه المشكلة.

لقد قمت بحل مشكلتي باستخدام طريقة ondrag عن طريق إزالة نموذج ng.
تحقق من هذا 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 (valueoftheslideronload) ؛
}) ؛

يعمل حل 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 التقييمات