2013-02-27 97 views
17

我剛開始玩弄AngularJS並試圖理解綁定技術。對於初學者來說,我試圖製作一個簡單的轉換計算器(幾十個片斷,幾十個片斷)。這工作很好,但是當我試圖既範圍輸入和輸入相同的模型屬性在調整範圍輸入不更新綁定。我有一個展示的行爲的jsfiddle:在AngularJS中與範圍和數字輸入的雙向綁定

的破碎和工作小提琴常見的JavaScript:

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> 

然而,結合2個投入相同的模型屬性似乎可以正常工作,如下圖所示:

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> 

任何想法如何得到範圍輸入綁定到AngularJS一個模型屬性?謝謝。

+0

我不認爲類型= 「範圍」 的支持:HTTPS:/ /github.com/angular/angular.js/issues/1189您可能必須爲它編寫自己的指令。 – 2013-02-27 15:59:13

回答

17

的這裏的問題是,輸入類型=「範圍」可與字符串並且不與號碼(而輸入類型=「數字」只適用於數字)。

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

範圍狀態表示該元素的值表示數字的字符串設置爲 的控制。

如果添加val = parseInt(val)爲您在qty二傳手第一條指令它應該工作:

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

的jsfiddlehttp://jsfiddle.net/bmleite/2Pk3M/2/

+14

基本上不是範圍輸入數字選擇?他們爲什麼使用字符串? – 2013-02-27 16:57:01

+6

它應該是'parseInt(val,10);' – 2014-06-12 01:43:57

+1

@LiviuT。他們可能使用了一個字符串來向後兼容。在不實現'type =「range」'的舊瀏覽器中,'input'仍然可以作爲文本字段使用,並且使用字符串類型'value'。在較新的瀏覽器上使'value'仍然是一個字符串可以避免瀏覽器兼容性錯誤。 – 2015-10-18 09:02:02

7

我覺得這個方案是比較通用的。

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

+0

我喜歡這個解決方案。雖然我用'Number'替換了'parseFloat' ;-) – joeytwiddle 2016-07-20 02:23:14

0

可以使用ng-model-options解決這個問題。我改變jsfiddle這裏是代碼:

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