如何在输入无线电值改变之前捕获它?

时间:2016-02-03 14:41:32

标签: javascript angularjs

我使用单选按钮选择表单中的内容类型

<input type="radio" ng-model="type" value="file" />
<input type="radio" ng-model="type" value="audio" />
<input type="radio" ng-model="type" value="video" />

我想了解以下代码

的内容
$scope.$watch('type', function(type, previousType) {
    if(!confirm('Are you sure you want to change the type?'))
        $scope.type = previousType;
});

显然,此代码会触发无限循环,因为$scope.type = previousType行会触发观察者。或类似的东西:

var ignore = false;
$scope.$watch('type', function(type, previousType) {
    if(!confirm('Are you sure you want to change the type?') && !ignore) {
        ignore = true;
        $scope.type = previousType;
        ignore = false;
    }
});

但是这个会引发竞争条件,ignore会在观察者触发之前重置为false

我还尝试将ng-model值存储在临时变量中,观察此变量,并在单选按钮上设置ng-selected="type == 'file'"(依此类推),但它也不起作用。

是否有一种优雅的方法来拦截价值并在实际ng-model更新之前对其进行测试?

2 个答案:

答案 0 :(得分:1)

您可以使用ng-click来完成此任务:

<input ng-click="changed()" type="radio" ng-model="my.type" value="file" />

var lastVal = false;
$scope.changed = function(){
  if (lastVal !== false && $scope.my.type != lastVal){
    if (!confirm('are you sure?')) {
        $scope.my.type = lastVal;
      return;
    }
  }
  lastVal = $scope.my.type;
}

http://jsfiddle.net/aws7uLwr/

注意:根据您的实施情况,这将触发那些可能会或可能不重要的元素的观察者。

编辑:评论中引用的替代答案:

var ignore = false;
$scope.$watch('type', function(type, previousType) {
  if (ignore){
    ignore = false;
    return;
  }
  if(!confirm('Are you sure you want to change the type?')) {
    ignore = true;
    $scope.type = previousType;
  }
});

答案 1 :(得分:0)

我不熟悉确切的语法(ng的东西),但试着解开&#34;解开&#34;在$scope.type = previousType;之前的手表,紧接在该行之后,重新绑定.$watch东西......

这样,当您重置.type时,它就不会触发&#34;观察者&#34;,您可以轻松避免无限循环,并且需要冗余&# 34;标志&#34; (代码中为ignore)。