在AngularJS中,如何直接监视$ scope变量并使用它来更新另一个变量很简单。但是,如果两个作用域变量需要相互监视,那么最佳实践是什么?
我有一个双向转换器,它将华氏温度转换为摄氏温度,反之亦然。如果您在华氏温度中键入“1”,则可以正常工作,但是尝试输入“1.1”,Angular会反弹一点,然后覆盖刚刚输入的华氏温度(1.1000000000000014):
function TemperatureConverterCtrl($scope) {
$scope.$watch('fahrenheit', function(value) {
$scope.celsius = (value - 32) * 5.0/9.0;
});
$scope.$watch('celsius', function(value) {
$scope.fahrenheit = value * 9.0 / 5.0 + 32;
});
}
这是一个小矮人:http://plnkr.co/edit/1fULXjx7MyAHjvjHfV1j?p=preview
有哪些不同的方法可以阻止Angular反弹,并强制其按原样使用您键入的值,例如通过使用格式化程序或解析器(或其他任何技巧)?
最佳答案
我认为最简单,最快和最正确的解决方案是使用一个标记来跟踪正在编辑的字段,并且仅允许对该字段进行更新。
您需要使用ng-change
指令在正在编辑的字段上设置标志。
Working Plunk
必要的代码更改:
修改 Controller ,使其看起来像这样:
function TemperatureConverterCtrl($scope) {
// Keep track of who was last edited
$scope.edited = null;
$scope.markEdited = function(which) {
$scope.edited = which;
};
// Only edit if the correct field is being modified
$scope.$watch('fahrenheit', function(value) {
if($scope.edited == 'F') {
$scope.celsius = (value - 32) * 5.0/9.0;
}
});
$scope.$watch('celsius', function(value) {
if($scope.edited == 'C') {
$scope.fahrenheit = value * 9.0 / 5.0 + 32;
}
});
}
然后将此简单指令添加到输入字段中(适当时使用
F
或C
):<input ... ng-change="markEdited('F')/>
现在,只有输入的字段可以更改另一个字段。
如果需要在输入之外修改这些字段的功能,则可以添加如下所示的作用域或 Controller 功能:
$scope.setFahrenheit = function(val) {
$scope.edited = 'F';
$scope.fahrenheit = val;
}
然后,摄氏温度字段将在下一个$ digest循环中更新。
该解决方案几乎没有额外的代码,消除了每个周期进行多次更新的可能性,并且不会引起任何性能问题。
关于data-binding - AngularJS中的华氏和摄氏双向转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17626202/