2013-02-27 28 views
17

Tôi chỉ mới bắt đầu chơi xung quanh với AngularJS và cố gắng để hiểu kỹ thuật ràng buộc. Để bắt đầu, tôi đã cố gắng để thực hiện một máy tính chuyển đổi đơn giản (hàng chục miếng, miếng để hàng chục). Đó là làm việc tốt, nhưng khi tôi đã cố gắng để ràng buộc cả một phạm vi đầu vào và một số đầu vào đối với tài sản cùng một mô hình các số đầu vào không cập nhật khi phạm vi giá trị được điều chỉnh. Tôi có một jsfiddle cho thấy các hành vi:Hai chiều ràng buộc với phạm vi và số đầu vào trong AngularJS

javascript phổ biến đối với bị phá vỡ và fiddles làm việc:

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> 

Tuy nhiên, ràng buộc hai số đầu vào cùng một thuộc tính mô hình có vẻ hoạt động tốt như được hiển thị trong fiddle này:

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> 

Bất kỳ ý tưởng làm thế nào để có được một loạt số đầu vào ràng buộc với một bất động sản mô hình duy nhất trong AngularJS? Cảm ơn.

+0

Tôi không nghĩ type = "phạm vi" được hỗ trợ: https://github.com/angular/angular.js/issues/1189 Bạn có thể sẽ phải viết chỉ thị của riêng bạn cho nó. –

Trả lời

17

Vấn đề ở đây là các input type = "phạm vi" làm việc với Strings và không phải với số (trong khi input type = "number" chỉ hoạt động với số).

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

Tình trạng phạm vi đại diện cho một điều khiển để thiết lập giá trị của phần tử để một chuỗi đại diện cho một số.

Nếu bạn thêm val = parseInt(val) như hướng dẫn đầu tiên của bạn trên qty setter cần làm việc:

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

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

+14

Không phải là đầu vào phạm vi về cơ bản là một số được chọn? Tại sao họ sử dụng dây? –

+6

Nó phải là 'parseInt (val, 10); ' –

+1

@LiviuT. Họ có thể sử dụng một chuỗi để tương thích ngược. Trên các trình duyệt cũ hơn không triển khai 'type =" range "', 'input' sẽ vẫn có thể sử dụng dưới dạng trường văn bản, với' giá trị 'kiểu chuỗi. Việc tạo 'giá trị' vẫn là một chuỗi trên các trình duyệt mới hơn tránh các lỗi tương thích với trình duyệt. –

7

Tôi nghĩ rằng giải pháp này là chung chung hơn.

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

Tôi thích giải pháp này. Mặc dù tôi đã thay thế 'parseFloat' bằng' Số' ;-) – joeytwiddle

0

Bạn có thể giải quyết nó bằng cách sử ng-model-options.Tôi đã thay đổi jsfiddle và đây là mã:

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; 
     } 
    }; 
}); 
Các vấn đề liên quan