在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;
    }
  });
}

然后将此简单指令添加到输入字段中(适当时使用FC):

<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/

10-10 10:14