17

我刚刚开始使用 AngularJS 并试图了解绑定技术。对于初学者,我尝试制作一个简单的转换计算器(几十到几,几到几十)。效果很好,但是当我尝试将范围输入和数字输入绑定到同一个模型属性时,调整范围值时数字输入不会更新。我有一个显示行为的 jsfiddle:

用于损坏和工作小提琴的常用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;
    });
}

断小提琴

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>

但是,将两个数字输入绑定到同一个模型属性似乎可以正常工作,如下面的小提琴所示:

工作小提琴

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中获取绑定到单个模型属性的范围数字输入?谢谢。

4

3 回答 3

17

这里的问题是输入类型=“范围”适用于字符串而不适用于数字(而输入类型=“数字”仅适用于数字)。

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

范围状态表示用于将元素的值设置为表示数字的字符串的控件。

如果您在setter上添加val = parseInt(val)第一条指令,它应该可以工作:qty

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

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

于 2013-02-27T16:04:15.567 回答
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);
        }
    }
};

});

完整的解释

于 2016-02-06T19:38:52.407 回答
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;
        }
     };
});
于 2016-02-20T10:14:12.023 回答