【问题标题】:Run function only the first time the user types in form input仅在用户第一次输入表单输入时运行功能
【发布时间】:2015-06-06 22:27:43
【问题描述】:

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

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

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

有没有更好的方法?如果你能提供一个例子,那就太好了。

【问题讨论】:

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


    【解决方案1】:

    这是一个简单的指令,应该可以满足您的需求。

    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】:

      $watch 不是为了那个。如果您从角度上下文之外更改某些内容,$watch 真的不会观看。

      您可以使用 ng-change 事件与输入进行交互,也可以使用自定义指令使用原始 javascript onChange 并最终调用 scope.$digest

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多