page - Enlace bidireccional con entrada de rango y número en AngularJS
router angular navigationend (3)
Estoy empezando a jugar con AngularJS y trato de entender la técnica de enlace. Para empezar, traté de hacer una calculadora de conversión simple (docenas a piezas, piezas a docenas). Eso funcionó bien, pero cuando intenté enlazar una entrada de rango y una entrada de número a la misma propiedad del modelo, la entrada de número no se actualiza cuando se ajusta el valor del rango . Tengo un jsfiddle mostrando el comportamiento:
javascript común para problemas rotos y de trabajo:
var myApp = angular.module(''myApp'', []);
myApp.controller(''CalcCtrl'', function ($scope) {
var num = 0.0;
$scope.qty = new Quantity(12);
$scope.num = num;
});
function Quantity(numOfPcs) {
var qty = numOfPcs;
var dozens = numOfPcs / 12;
this.__defineGetter__("qty", function () {
return qty;
});
this.__defineSetter__("qty", function (val) {
qty = val;
dozens = val / 12;
});
this.__defineGetter__("dozens", function () {
return dozens;
});
this.__defineSetter__("dozens", function (val) {
dozens = val;
qty = val * 12;
});
}
html:
<div ng-controller="CalcCtrl">
<form>
<label for="pcs">Pieces:</label>
<input type="number" min="0" ng-model="qty.qty" size="20" id="pcs"
/>
<input type="range" min="0" max="100" ng-model="qty.qty" />
<br/>
<label for="numOfDozens">Dozens</label>
<input type="number" min="0" ng-model="qty.dozens" size="20"
id="numOfDozens" />
</form>
</div>
Sin embargo, el enlace de dos entradas numéricas a la misma propiedad del modelo parece funcionar bien, como se muestra en este violín:
html:
<div ng-controller="CalcCtrl">
<form>
<label for="pcs">Pieces:</label>
<input type="number" min="0" ng-model="qty.qty" size="20" id="pcs"
/>
<input type="number" min="0" max="100" ng-model="qty.qty" />
<br/>
<label for="numOfDozens">Dozens</label>
<input type="number" min="0" ng-model="qty.dozens" size="20"
id="numOfDozens" />
</form>
</div>
¿Alguna idea de cómo obtener una entrada de rango y número vinculada a una sola propiedad de modelo en AngularJS? Gracias.
Creo que esta solución es más genérica.
myApp.directive(''input'', function() {
return {
restrict: ''E'',
require: ''?ngModel'',
link: function(scope, element, attrs, ngModel) {
if (''type'' in attrs && attrs.type.toLowerCase() === ''range'') {
ngModel.$parsers.push(parseFloat);
}
}
};
});
El problema aquí es que el tipo de entrada = "rango" funciona con cadenas y no con números (mientras que el tipo de entrada = "número" solo funciona con números).
http://www.w3.org/wiki/HTML/Elements/input/range
El estado del rango representa un control para establecer el valor del elemento en una cadena que representa un número.
Si agrega val = parseInt(val)
como su primera instrucción en el programador de qty
, debería funcionar:
this.__defineSetter__("qty", function (val) {
val = parseInt(val);
qty = val;
dozens = val / 12;
});
jsfiddle : http://jsfiddle.net/bmleite/2Pk3M/2/
Puedes resolverlo usando ng-model-options
. Cambié jsfiddle y aquí está el código:
html :
<div ng-controller="CalcCtrl">
<form>
<label for="pcs">Pieces:</label>
<input type="number" min="0" ng-model="qty.qty" size="20" id="pcs" ng-model-options="{ getterSetter: true }"/>
<input type="range" min="0" max="100" ng-model="qty.qty" ng-model-options="{ getterSetter: true }"/>
<br/>
<label for="numOfDozens">Dozens</label>
<input type="number" min="0" ng-model="qty.dozens" size="20"
id="numOfDozens" ng-model-options="{ getterSetter: true }"/>
</form>
</div>
js
var myApp = angular.module(''myApp'', []);
myApp.controller(''CalcCtrl'', function ($scope) {
var num = 1.0;
$scope.qty = {
qty:function (val) {
return arguments.length ? (num = parseFloat(val)) : num;
},
dozens: function (val) {
return arguments.length ? (num = val*12) : num/12;
}
};
});