为了账号安全,请及时绑定邮箱和手机立即绑定

AngularJS浏览器通过使用指令自动填充的解决方法

/ 猿问

AngularJS浏览器通过使用指令自动填充的解决方法

ibeautiful 2019-11-11 13:04:06

在AngularJS中提交表单并使用浏览器时,请记住密码功能,并且在随后的登录尝试中,让浏览器使用用户名和密码填写登录表单,该$scope模型不会基于自动填充进行更改。


我发现的唯一肮脏的技巧是使用以下指令:


app.directive("xsInputSync", ["$timeout" , function($timeout) {

    return {

        restrict : "A",

        require: "?ngModel",

        link : function(scope, element, attrs, ngModel) {

            $timeout(function() {

                if (ngModel.$viewValue && ngModel.$viewValue !== element.val()) {

                    scope.apply(function() {

                        ngModel.$setViewValue(element.val());

                    });

                }

                console.log(scope);

                console.log(ngModel.$name);

                console.log(scope[ngModel.$name]);

            }, 3000);

        }

    };

}]);

问题在于,ngModel.$setViewValue(element.val());基于element.val()返回的值不会更改模型或视图。我该怎么做?


查看完整描述

3 回答

?
慕田峪7331174

显然,这是Angular的已知问题,目前已打开


除了像您正在尝试的工作以外,我不确定您可以在这里做什么。看来您步入正轨。我无法让我的浏览器记住您的密码,因此不确定是否可以使用,但请看一下:


app.directive('autoFillSync', function($timeout) {

   return {

      require: 'ngModel',

      link: function(scope, elem, attrs, ngModel) {

          var origVal = elem.val();

          $timeout(function () {

              var newVal = elem.val();

              if(ngModel.$pristine && origVal !== newVal) {

                  ngModel.$setViewValue(newVal);

              }

          }, 500);

      }

   }

});

<form name="myForm" ng-submit="login()">

   <label for="username">Username</label>

   <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>

   <label for="password">Password</label>

   <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>

   <button type="submit">Login</button>

</form>

我认为您只需要稍微简化一下方法即可。我绝对推荐的一件事是检查ngModel.$pristine并确保您不会覆盖某些不良用户的输入。另外,3秒可能太长。您不必在$ timeout中调用$ apply(),顺便说一句,它应该为您自动排队$ digest。


真正的收获是:您的浏览器会击败Angular来执行吗?那我的浏览器呢?


这可能是一场无法战胜的战争,这就是Angular(或淘汰赛)无法轻松解决它的原因。指令初次执行时,无法保证输入中数据的状态。甚至在Angular初始化时也没有。...因此,这是一个棘手的问题。


查看完整回答
反对 回复 2019-11-11
?
MMTTMM

您不必使用$timeout或类似的东西。您可以使用事件系统。


我认为它更像Angularish,并且不依赖于jQuery或自定义事件捕获。


例如,在您的提交处理程序上:


$scope.doLogin = function() {

    $scope.$broadcast("autofill:update");


    // Continue with the login.....

};

然后,您可以有一个autofill像这样的指令:


.directive("autofill", function () {

    return {

        require: "ngModel",

        link: function (scope, element, attrs, ngModel) {

            scope.$on("autofill:update", function() {

                ngModel.$setViewValue(element.val());

            });

        }

    }

});

最后,您的HTML将如下所示:


<input type="text" name="username" ng-model="user.id" autofill="autofill"/>


查看完整回答
反对 回复 2019-11-11
?
慕田峪9158850

这是一个解决方案,其安全性远低于提出的其他解决方案,并且在语义上是AngularJS的:http : //victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/


myApp.directive('formAutofillFix', function() {

  return function(scope, elem, attrs) {

    // Fixes Chrome bug: https://groups.google.com/forum/#!topic/angular/6NlucSskQjY

    elem.prop('method', 'POST');


    // Fix autofill issues where Angular doesn't know about autofilled inputs

    if(attrs.ngSubmit) {

      setTimeout(function() {

        elem.unbind('submit').submit(function(e) {

          e.preventDefault();

          elem.find('input, textarea, select').trigger('input').trigger('change').trigger('keydown');

          scope.$apply(attrs.ngSubmit);

        });

      }, 0);

    }

  };

});

然后,您只需将指令附加到表单:


<form ng-submit="submitLoginForm()" form-autofill-fix>

  <div>

    <input type="email" ng-model="email" ng-required />

    <input type="password" ng-model="password" ng-required />

    <button type="submit">Log In</button>

  </div>

</form>


查看完整回答
反对 回复 2019-11-11

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信