http://stackoverflow.com/questions/14965968/angularjs-browser-autofill-workaround-by-using-a-directive
Apparently this is a known issue with Angular and is currently open
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>
我的想法
印象中以前查的時候好像還沒有丟出這個 auto-fill-sync
的 directive,所以這次真的碰到要解決這個問題,我很快的想到應該實驗一下 browser 的 autofill 是不是真的會在 <input>
裡 fill 進東西。
如果只是 AngularJS 那邊沒有抓到 autofill 的動作,應該就還算好解決,只要想辦法通知 AngularJS 就好了。
怕是怕 browser 是直到你確定要送出前夕才塞入 autofill 的值,這樣誰也幫不了我了~~~
$('#username').val();
// output: "我的帳號"
好加在實驗結果是後者 (呼)
於是我寫了一個自己的版本(因為沒有先看 stackoverflow 那篇…)
/* file: autocomplete-fix.js */
app.directive('autocompleteFix', ['$timeout', '$log', function ($timeout, $log) {
return {
require: 'ngModel',
restrict: 'A',
link: function postLink(scope, iElm, iAttrs, ctrl) {
/**
* Delay for 450ms works for Chrome on OS X
*/
var _delay = 450;
if (iAttrs.autocompleteFix) {
_delay = parseInt(iAttrs.autocompleteFix, 10);
}
$log.debug('delay', _delay);
$timeout(function () {
ctrl.$setViewValue(iElm.val());
}, _delay);
}
};
}]);
有趣的地方是,_delay
在 300, 400 時,都會有機會沒通知到 AngularJS,所以我自己試的恰當值大約是 450(而 stackoverflow 上的是 500)。
感覺 stackoverflow 上的版本似乎考慮比較周到,所以就留個 gist 存著吧!