我需要选择以kg和磅为单位的重量。但我的modelValue应始终包含以千克为单位的值。
所以我创建了以下HTML。
<div>
<label>{{'aircraftModal.mtom' | translate}}:</label>
<label><input type="radio" name="weightRadio" ng-model="AircraftCtrl.weightRepresentation" ng-value="'kg'" >Kilogram</label>
<label><input type="radio" name="weightRadio" ng-model="AircraftCtrl.weightRepresentation" ng-value="'pound'">Pound</label>
<input type="number" step="0.01" ng-model="AircraftCtrl.mtom" weight weight-representation="AircraftCtrl.weightRepresentation">
</div>
我制作了一个带有weight
属性的指令weigt-representation
。该指令将解析/格式化我在视图/控制器中的值。
angular.module('app.directives').directive('weight', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
weightRepresentation: "=weightRepresentation"
},
link: function(scope, elem, attrs, ngModelController) {
var conversionPoundsToKilogram = 0.45359237;
ngModelController.$formatters.unshift(function(valueFromModel) {
if(!valueFromModel) return valueFromModel;
if(scope.weightRepresentation === 'pound'){
valueFromModel = valueFromModel / conversionPoundsToKilogram;
}
return parseFloat(valueFromModel).toFixed(2);
});
ngModelController.$parsers.push(function(valueFromInput) {
if(!valueFromInput) return valueFromInput;
if(scope.weightRepresentation === 'pound'){
valueFromInput = valueFromInput * conversionPoundsToKilogram;
}
return valueFromInput;
});
scope.$watch('weightRepresentation', function(newWeight, oldWeight){
if(ngModelController.$modelValue){
console.log("before " + ngModelController.$modelValue);
ngModelController.$modelValue = ngModelController.$modelValue - 1;
console.log("After" + ngModelController.$modelValue);
}
});
}
};
});
问题在于每当我改变单选按钮时,我都需要re-format the viewValue
。所以我应该只重新运行格式化程序。我更红格式化格式化程序只有在更改modelValue时才会被激活。出于这个原因,我添加了ngModelController.$modelValue = ngModelController.$modelValue - 1;
。格式化程序会被调用,但valueFromModel
不包含已编辑的值,而是包含减1之前的值。
Tbh,它完全符合我的需求,但我不明白它为什么会起作用
此外,modelValue可以包含任意数量的小数位数,而viewValue应该固定为2位小数
我的问题: 1.为什么会出现这种行为? 2.这是在不改变实际modelValue的情况下引导格式化程序重新运行的正确方法,还是这只是一个肮脏的黑客攻击?
答案 0 :(得分:2)
这是一个肮脏的黑客,使用$ setViewValue来更改viewValue,因为你实现了在更改viewValue时将被调用的$解析器,它将正常工作。
关于你的工作:ngModelController在他的ngModel上有一个监视器,因此如果你改变它就可以刷新视图。
编辑:从我上一篇评论中添加示例代码,该代码是作者接受的代码:如果最后一次更改只是单位更改,则使用标记不更改ngModel:
var unitChanged = false;
scope.$watch('weightRepresentation', function(newWeight, oldWeight){
if(ngModelController.$modelValue){
unitChanged = true;
// compute new viewValue and update it using $setViewValue
[...]
}
});
ngModelController.$parsers.push(function(valueFromInput) {
if(!valueFromInput) return valueFromInput;
if(unitChanged){
unitChanged = false;
return ngModelControler.$modelValue;
}
[...]// normal code
});
注意那些3个javascript指令的顺序不计算,我只是命令它这样更具可读性有答案。