Two-way binding with range and number input in AngularJS

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I'm just starting to play around with AngularJS and trying to understand the binding technique. For starters, I tried to make a simple conversion calculator (dozens to pieces, pieces to dozens). That worked well, but when I tried to bind both a range input and a number input to the same model property the number input does not update when the range value is adjusted. I have a jsfiddle showing the behavior:

common javascript for broken and working fiddles:

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;     }); } 

BROKEN FIDDLE

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> 

However, binding two number inputs to the same model property seems to work fine as shown in this fiddle:

WORKING FIDDLE

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> 

Any ideas how to get a range and number input bound to a single model property in AngularJS? Thanks.

回答1:

The problem here is that the input type="range" works with Strings and not with Numbers (while input type="number" only works with Numbers).

http://www.w3.org/wiki/HTML/Elements/input/range

The range state represents a control for setting the element's value to a string representing a number.

If you add val = parseInt(val) as your first instruction on the qty setter it should work:

this.__defineSetter__("qty", function (val) {             val = parseInt(val);     qty = val;     dozens = val / 12; }); 

jsfiddle: http://jsfiddle.net/bmleite/2Pk3M/2/



回答2:

I think this solution is more generic.

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);         }     } }; 

});

full explanation



回答3:

You can solve it using ng-model-options. I changed jsfiddle and here is the code:

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;         }      }; }); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!