仅在用户第一次键入表单输入时运行函数

时间:2015-04-02 04:23:20

标签: javascript angularjs angularjs-directive angular-ngmodel angularjs-watch

这应该是直截了当的,但尚未找到解决方案。

我在input中有一个form。我想检测用户何时与输入交互并运行javascript函数一次,如果有的话。

我一直在考虑使用$watch检测input元素是否具有类ng-dirty,如果有,请运行js函数并取消绑定监视。

有更好的方法吗?如果你能提供一个例子,那将会很棒。

3 个答案:

答案 0 :(得分:2)

$ watch不是为了那个。如果你从角度背景之外改变某些东西,$ watch真的不会看。

您可以使用ng-change事件进行交互式输入或使用原始javascript onChange使用自定义指令和调用范围。$ digest finally

简单的解决方案是使用ng-change:

<input type="text" name="test" ng-change="doChanges()" />

答案 1 :(得分:2)

这是一个简单的指令,应该做你想要的。

angular.module('myApp', [])
.controller('MyCtrl', function($scope) {
  $scope.bar = function() {
    console.log('bar was called!');
    $scope.barWasCalled = true;
  };
})
.directive('once', function() {
  return {
    require: 'ngModel',
    scope: {
      fn: '&once'
    },
    link: function($scope, $element, $attrs, ngModel) {
      // add a listener and save the index for removal
      var idx = ngModel.$viewChangeListeners.push(function() {
        // user typed, run the function
        $scope.fn();
        // remove the listener
        ngModel.$viewChangeListeners.splice(idx, 1);
      }) - 1;
    }
  };
})
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
  <input type="text" ng-model="foo" once="bar()" placeholder="type something...">
  <div ng-show="barWasCalled">Bar was called!</div>
</div>

$viewChangeListener提供的性能比$watch更好,但无论如何它都是名义上的。

请记住将任何类型的DOM相关行为放入指令中。这使事情变得轻松而整洁。

答案 2 :(得分:0)

您还可以在指令上使用$ watchCollection。它返回一个取消注册函数,您可以调用它来取消绑定表单上的监视。这样做的好处是它可以监视表单,而不是模型或任何特定输入。这样,只要修改了表单上的任何输入,就会执行并删除$ watchCollection的回调函数。

&#13;
&#13;
(function() {
  'use strict';

  angular.module('app', []);

  angular.module('app')
    .directive('mainForm', mainForm);

  mainForm.$inject = ['$log'];

  function mainForm($log) {
    var directive = {
      restrict: "A",
      scope: {
        myForm: "=ngForm"
      },
      link: link
    };

    return directive;

    function link(scope, element, attrs, controller) {
      var undoWatch = scope.$watchCollection('myForm', function(newVal, oldVal) {
        //check if the form is dirty
        if (newVal.$dirty) {
          alert("do this one time!");
          //unbind the function so we don't do it again
          undoWatch();
        }
      });
    }

  }
})();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-app="app">
  <h1>Do Action Once Example</h1>
  <div ng-form="example" main-form novalidate>
    <p> Use any input on the page to alert the user one time.</p>
    <input ng-model="inputVal" type="text" class="form-control" />
    <input ng-model="anotherInputVal" type="checkbox" class="form-control" />
  </div>
  <p>{{ inputVal }}</p>
</body>

</html>
&#13;
&#13;
&#13;