AngularJS中结合函数与ng-model实现单位转换器的问题
AngularJS 毫米/英寸双向单位转换器实现方案
核心问题在于没有区分模型存储值和界面显示值:要么用固定初始值导致输入框无法编辑,要么直接绑定模型却没处理单位转换逻辑。下面是基于自定义指令的解决方案,能同时满足输入可编辑、单位切换自动转换的需求:
实现思路
- 统一用一种单位(比如毫米)存储模型数据,保证数据一致性
- 自定义指令处理模型值与显示值的双向转换:
- 从模型到界面:把存储的毫米值转换成当前选中单位的数值
- 从界面到模型:把用户输入的当前单位数值转换成毫米值存储
- 单位切换时触发指令更新界面显示值
完整代码示例
HTML 部分
<div ng-app="UnitConverterApp" ng-controller="MainCtrl"> <!-- 位置X输入框 --> <div> <label>X位置:</label> <input type="number" step="0.01" unit-converter ng-model="shape.x" current-unit="currentUnit"> </div> <!-- 形状宽度输入框 --> <div> <label>形状宽度:</label> <input type="number" step="0.01" unit-converter ng-model="shape.width" current-unit="currentUnit"> </div> <button ng-click="toggleUnit()">切换单位(当前:{{currentUnit}})</button> <p>模型原始值(毫米):X={{shape.x}},宽度={{shape.width}}</p> </div>
JavaScript 部分
angular.module('UnitConverterApp', []) .controller('MainCtrl', function($scope) { // 模型数据:统一用毫米存储 $scope.shape = { x: 50, width: 150 }; $scope.currentUnit = 'mm'; // 切换单位的方法 $scope.toggleUnit = function() { $scope.currentUnit = $scope.currentUnit === 'mm' ? 'in' : 'mm'; // 广播单位变化事件,通知所有转换器指令更新显示 $scope.$broadcast('unitChanged'); }; }) .directive('unitConverter', function() { return { require: 'ngModel', scope: { currentUnit: '=', ngModel: '=' }, link: function(scope, element, attrs, ngModelCtrl) { // 单位转换系数:1英寸 = 25.4毫米 const MM_PER_INCH = 25.4; // 模型值(毫米)转显示值 function modelToView(value) { if (!value) return 0; if (scope.currentUnit === 'in') { return (value / MM_PER_INCH).toFixed(2); // 保留两位小数 } return value.toFixed(2); } // 显示值转模型值(毫米) function viewToModel(value) { if (!value) return 0; if (scope.currentUnit === 'in') { return parseFloat(value) * MM_PER_INCH; } return parseFloat(value); } // 格式化模型值到界面 ngModelCtrl.$formatters.push(modelToView); // 解析界面输入到模型 ngModelCtrl.$parsers.push(viewToModel); // 监听单位变化事件,更新界面显示 scope.$on('unitChanged', function() { ngModelCtrl.$setViewValue(modelToView(scope.ngModel)); ngModelCtrl.$render(); }); } }; });
关键细节说明
- 模型值统一用毫米存储,避免多单位存储导致的数据混乱
- 指令里的
$formatters和$parsers是AngularJS处理ngModel双向绑定的核心钩子,分别负责模型到视图、视图到模型的转换 - 切换单位时通过
$broadcast发送事件,所有绑定了指令的输入框都会自动更新显示值 - 加入
step="0.01"和toFixed(2)保证小数精度,适合设计类应用的需求 - 支持多个输入框复用指令,只需要绑定不同的模型字段即可
内容的提问来源于stack exchange,提问作者rockstiff
相关产品推荐
相关产品推荐

