Basicamente, uma entrada de intervalo é configurada com um valor inicial usando o modelo ng. O valor real do elemento HTML e a posição do controle deslizante de intervalo estão incorretos. Eu esperaria que a posição do controle deslizante e o valor de entrada html estivessem em sincronia com a variável do modelo.
Aqui está uma reprodução: http://jsfiddle.net/fschwiet/HVp2J/
Verificado no Chrome e Firefox em execução no Windows 8.
Vejo que há outros problemas abertos para entrada [type = range], não está claro se eles estão relacionados.
Isso ainda é um problema com o Angular 1.2.14: http://jsfiddle.net/HVp2J/7/
Como solução alternativa, pode-se definir o valor do modelo em um manipulador $ timeout.
$ timeout não ajuda, o problema permanece.
@fschwiet : http://jsfiddle.net/HVp2J/9/
@ Rajat-Chowdhary Desculpe, eu deveria ter incluído um exemplo de código mostrando como $ timeout pode funcionar como solução alternativa :
A solução alternativa parece arriscada, pois o valor do modelo não pode ser inicializado até o retorno de chamada $ timeout para que a solução alternativa funcione.
Parece que encontrei o problema.
Angular define o valor antes de definir min, max e step, de forma que parece que o intervalo está na posição errada. Para resolver o problema, usei esta diretiva
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);
});
}
};
});
Aqui está a nova versão do ngRange sem escopo privado:
.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);
}
});
}
};
});
isso ainda é um problema, certo?
Sim +1
Sim, ainda é um problema.
Eu perguntei algo semelhante em stackoverflow como inicializar o valor de uma entrada [range] usando AngularJS quando o valor está acima de 100 . Usando 1.4.0-beta.build.3791, esse bug ainda está presente.
+1
+1, e ficou pior quando a faixa de entrada é acoplada a um número de entrada.
1 para este problema
Enfrentando o mesmo problema: +1
sim - mesmo problema +1
este é o HTML5 básico - qual é o status disso, alguém está trabalhando nisso?
levando isso em consideração: https://github.com/danielcrisp/angular-rangeslider/issues/51
onde Error: ngModel: numfmt controle deslizante de intervalo é lançado
Eu ajustei a solução @ ardf69 para isso:
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, tenho o mesmo problema ao alternar [tipo de entrada = intervalo] com ng-if
Também me deparei com esse problema e escrevi uma pergunta sobre Stack Overflow sobre isso, “Em Angular, vincular o atributo da variável de escopo _before_ ngModel vincula a entrada value
” . A questão inclui um trecho de código executável que reproduz esse problema.
Algumas soluções alternativas foram publicadas como respostas no Stack Overflow. O aplicável ao meu caso envolve o uso de manipulação DOM com $inputElement.prop()
para definir os valores de min
, max
e step
(quaisquer atributos necessários). Ao fazer essa manipulação DOM antes do meu directiva costume está subjacente <input>
's value
é primeiro set, I evitar o problema.
Minha maneira preguiçosa de resolver esse bug era dividir os valores mín. / Máx. E os valores da etapa por 100. Assim, 300 se torna 3,0, etc. e os valores ficam abaixo de 100. Então, multiplico as coisas de volta conforme necessário. Talvez seja útil para alguém.
+1 Isso é muito chato.
+1
+1
+1
Outra solução alternativa preguiçosa:
$timeout(function () {
angular.element('.slider-input').val(amount);
});
+1
Com o novo recurso Reactions do GitHub, você não precisa mais comentar “+1”. Em vez disso, você pode marcar seu interesse clicando em “+: sorrir:” no canto superior direito do primeiro comentário neste problema e, em seguida, escolher: +1: (“+1”). Isso evita o envio de uma notificação inútil para todos os inscritos neste problema.
Resolvi meu problema usando o método ondrag removendo o modelo ng.
verifique este http://codepen.io/nagarajumusini/pen/BKpGJz
+1
+1
Adicionar ng-init à entrada funciona para mim para definir o valor inicial
<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" />
Solução encontrada em:
Estamos trabalhando nisso (finalmente). Fechando como uma duplicata de https://github.com/angular/angular.js/issues/5892
$ (document) .ready (function () {
angular.element ('.suaclasseaqui'). val (valueoftheslideronload);
});
esta solução alternativa do jQuery funciona para que você possa definir um valor quando a página for carregada, mas seja qual for o valor dos controles deslizantes, não sincronizará até que seja tocado.
@davedx Talvez esta seja a melhor maneira antes que o problema seja resolvido.
<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>
Comentários muito úteis
Com o novo recurso Reactions do GitHub, você não precisa mais comentar “+1”. Em vez disso, você pode marcar seu interesse clicando em “+: sorrir:” no canto superior direito do primeiro comentário neste problema e, em seguida, escolher: +1: (“+1”). Isso evita o envio de uma notificação inútil para todos os inscritos neste problema.