javascript - 当输入集中时,不会更新 ng-model

标签 javascript angularjs angular-ngmodel angularjs-ng-model

我正在制定一个指令,该指令将在聚焦时阻止输入的渲染。

用例是我们从后端接收频繁的实时更新,并且由于 ng-model 绑定(bind),它将覆盖用户在输入中写入的任何内容。 我们按 Enter 键发送更新,使用 ng-keydown="($event.keyCode === 13) ? $ctrl.setItem($event, $ctrl.item) : return"其中 $ctrl.setItem 将向后端发送请求。

我几乎让它按照我想要的方式工作,只是当我在编辑后模糊输入时得到了令人惊讶的结果。

我做了一个 plunker,使用 $interval: https://plnkr.co/edit/XNFA3bQtbGliAhS0uVmP?p=preview 模拟后端更新。

app.directive('noUpdatesWhenFocused', function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, element, attrs, ngModel) {
      if (!ngModel || element[0].type !== 'text') {
        return;
      }

      var hasFocus = false;
      element.on('focus', function() {
        hasFocus = true;
      });
      element.on('blur', function() {
        hasFocus = false;
        ngModel.$render();
      });

      ngModel.$render = function() {
        if (!hasFocus) {
          element.val(ngModel.$viewValue);
        }
      };
    }
  };
});

如果在第一个输入字段中进行编辑后模糊并等待几秒钟以进行新的“更新”,则模型将恢复到上次 View 编辑的状态,而不是上次模型更新的状态。我们总是想显示后端的最新更新,所以这就是我需要解决的问题,但我很困惑。

最佳答案

好吧,我明白了。 ngModel.$pasers 在模糊事件之前被触发。因此,我添加了一个解析器,如果 viewValue 与上次调用解析器相比没有发生变化,则该解析器会忽略它,而如果您进行模糊处理,则不会发生变化。

var app = angular.module('myApp', []);

app.directive('noUpdatesWhenFocused', function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, element, attrs, ngModel) {
      if (!ngModel || element[0].type !== 'text') {
        return;
      }

      var hasFocus = false;
      element.on('focus', function() {
        hasFocus = true;
      });
      element.on('blur', function() {
        hasFocus = false;
        ngModel.$render();
      });
      
      ngModel.$render = function() {
        if (!hasFocus) {
          element.val(ngModel.$viewValue);
        }
      };
      
      var vValue = ngModel.$viewValue;
      ngModel.$parsers.unshift(function(viewValue) {
        var returnValue = viewValue === vValue ? ngModel.$modelValue : viewValue;
        ngModel.$setViewValue(returnValue);
        ngModel.$render();
        vValue = viewValue;
        return returnValue;
      });
    }
  };
});

app.run(function($rootScope, $interval) {
  $rootScope.item = 'item';
  $interval(function(count) {
    if (typeof count === 'number') {
      if($rootScope.item) {
        $rootScope.item = $rootScope.item + '' + count;
      }
      else {
        $rootScope.item = '' + count;
      }
      console.log($rootScope.item);
    }
  },3000);
});
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
  <script src="script.js"></script>
</head>
<body ng-app="myApp">
  <form name="myForm">
    <input
      no-updates-when-focused
      name="item1"
      ng-model="item"
      size="50"
      required>
    </input>
    <span ng-show="myForm.item1.$error.required">Required!</span>
    </br>
    <input
      name="item2"
      ng-model="item"
      size="50"
      required>
    </input>
    <span ng-show="myForm.item2.$error.required">Required!</span>
  </form>
</body>
</html>

关于javascript - 当输入集中时,不会更新 ng-model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38174641/

相关文章:

javascript - AngularJS 指令中具有相同 ng-model 的多个输入元素

javascript - TinyMCE - 如何使用 onClick 而不是 <a href =""> 作为链接?

c# - 无法将当前json数组反序列化为类型

使用单选按钮和 ng-repeat 进行 AngularJS 表单验证

javascript - 我可以使用 ng-repeat 并具有带有 Angular 分量的隔离范围吗?

javascript - ng-model 未正确更新(angular-ui-tinymce)

javascript - Angular以编程方式添加没有属性的ngChange

javascript - 如何强制 js 忽略 Uncaught Error 并继续工作?

javascript - 调用 JavaScript 函数会改变参数的值。为什么?

javascript - 在不使用 Jquery 的情况下单击即可循环浏览 div 内容