讓angularjs支持瀏覽器自動(dòng)填表
最近有很多前端同學(xué)都抱怨說(shuō),登陸表單都不能記錄自己的賬號(hào)。這對(duì)于用單頁(yè)面(single-page applications)和使用ajax比較多的網(wǎng)頁(yè)來(lái)說(shuō),還是一個(gè)蠻普遍的問(wèn)題。
UserApp是一個(gè)使用angularjs構(gòu)建的WebApp,但是他一直未能支持瀏覽器的"save password"特性。
下面就列出了一些發(fā)現(xiàn)的問(wèn)題:
表單不能用js動(dòng)態(tài)的插入DOM。
表單必須真正的發(fā)出一個(gè)POST請(qǐng)求。(不能獲取表單內(nèi)容,然后用ajax發(fā)出請(qǐng)求)
當(dāng)瀏覽器自動(dòng)填表后,$scope并不能獲得更新后的數(shù)據(jù)。
Firefox相對(duì)來(lái)說(shuō)簡(jiǎn)單一點(diǎn),只要表單元素有name屬性,觸發(fā)提交事件之后,它就會(huì)自動(dòng)提醒用戶是否記錄數(shù)據(jù)。
<form name="login-form" ng-submit="login()">
<input id="login" name="login" type="text" ng-model="user.login">
<input id="password" name="password" type="password" ng-model="user.password">
</form>
firefox記錄數(shù)據(jù)的要求比較簡(jiǎn)單

但是firefox有一個(gè)問(wèn)題,在自動(dòng)填表之后,$scope里的數(shù)據(jù)并不會(huì)更新。所以我google了一下,發(fā)現(xiàn)了一些針對(duì)此問(wèn)題的hacks。但是總感覺(jué)這些解決方案沒(méi)必要,因?yàn)槲倚枰闹皇窃谔峤槐韱蔚臅r(shí)候?qū)?shù)據(jù)帶上,而不是一些很溜逼的數(shù)據(jù)雙向綁定技術(shù)。所以我就采用了很簡(jiǎn)單的辦法:在提交表單的時(shí)候獲取表單元素的值。
$scope.login = function() {
$scope.user = {
login: $("#login").val(),
password: $("#password").val()
};
...
return false;
};
OK,現(xiàn)在firefox沒(méi)問(wèn)題了,但是chrome怎么辦呢?
chrome只有在form表單真正發(fā)起POST請(qǐng)求的時(shí)候才會(huì)提示用戶是否儲(chǔ)存密碼,但這樣的話就不能用Ajax操作了。
下面是解決辦法:
當(dāng)表單發(fā)出Post請(qǐng)求時(shí),用ng-submit截取,返回false將其阻止,同時(shí)用ajax提交數(shù)據(jù)。
當(dāng)ajax成功返回時(shí),將session儲(chǔ)存在cookies里,再將表單重新提交一邊。
頁(yè)面重載的時(shí)候會(huì)發(fā)現(xiàn)已經(jīng)認(rèn)證過(guò)了,就將其重定向到主頁(yè)。
這會(huì)讓頁(yè)面刷新一次,但也就是登錄的時(shí)候需要刷新而已,確保頁(yè)面返回時(shí)是同一個(gè)地址就行了。
但如果表單是被動(dòng)態(tài)添加進(jìn)DOM的時(shí)候,這個(gè)方法仍然不行。解決方案就是在index.html中添加一個(gè)隱藏的表單,需要提交數(shù)據(jù)的時(shí)候就將其它表單攜帶的數(shù)據(jù)復(fù)制到隱藏表單里。
我將它打包成了一個(gè)directive:
app.directive("ngLoginSubmit", function(){
return {
restrict: "A",
scope: {
onSubmit: "=ngLoginSubmit"
},
link: function(scope, element, attrs) {
$(element)[0].onsubmit = function() {
$("#login-login").val($("#login", element).val());
$("#login-password").val($("#password", element).val());
scope.onSubmit(function() {
$("#login-form")[0].submit();
});
return false;
};
}
};
});
在index.html里隱藏的表單:
<form name="login-form" id="login-form" method="post" action="" style="display: none;">
<input name="login" id="login-login" type="text">
<input name="password" id="login-password" type="password">
</form>
臨時(shí)登錄表單
<form name="login-form" autocomplete="on" ng-login-submit="login">
<input id="login" name="login" type="text" autocomplete="on">
<input id="password" name="password" type="password" autocomplete="on">
</form>
登錄用的controller:
$scope.login = function(submit) {
$scope.user = {
login: $("#login").val(),
password: $("#password").val()
};
function ajaxCallback() {
submit();
}
return false;
};
刷新時(shí)會(huì)提示是否重新提交表單

現(xiàn)在這個(gè)問(wèn)題解決了,但是每當(dāng)你按下f5的時(shí)候,瀏覽器都會(huì)提醒你要不要重新提交表單。這確實(shí)有點(diǎn)蛋疼,所以我添加了一個(gè)pre-login.html文件,隱藏的表單會(huì)提交數(shù)據(jù)到這里,然后再重定向到index.html。
現(xiàn)在OK了~
相關(guān)文章
淺談AngularJS中$http服務(wù)的簡(jiǎn)單用法
這篇文章主要介紹了淺談AngularJS中$http服務(wù)的簡(jiǎn)單用法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Angular動(dòng)態(tài)綁定樣式及改變UI框架樣式的方法小結(jié)
AngularJS 是一個(gè) JavaScript 框架。它是一個(gè)以 JavaScript 編寫(xiě)的庫(kù)。這篇文章主要介紹了Angular動(dòng)態(tài)綁定樣式及改變UI框架樣式的方法小結(jié),需要的朋友可以參考下2018-09-09
AngularJs Using $location詳解及示例代碼
本文主要介紹AngularJs Using $location的知識(shí)資料,這里整理了相關(guān)的資料,及簡(jiǎn)單示例代碼,有興趣的小伙伴可以參考下2016-09-09
angular學(xué)習(xí)之從零搭建一個(gè)angular4.0項(xiàng)目
本篇文章主要介紹了從零搭建一個(gè)angular4.0項(xiàng)目,主要用到的工具angular4.0、angular-cli、npm(v3.10.8)、node(v6.2.0),有興趣的可以了解一下2017-07-07
Angular2中Bootstrap界面庫(kù)ng-bootstrap詳解
不知道大家有沒(méi)有留意,最近angular-ui團(tuán)隊(duì)終于正式發(fā)布了基于 Angular2的Bootstrap界面庫(kù)ng-bootstrap ,之前工作中一直在用 AngularJS 1.x 的UI Bootstrap , 因此對(duì)這個(gè)ng-bootstrap 也是很感興趣,所以第一時(shí)間進(jìn)行試用。這篇文章就給大家詳細(xì)介紹下ng-bootstrap。2016-10-10
angularjs 處理多個(gè)異步請(qǐng)求方法匯總
這篇文章主要介紹了angularjs 處理多個(gè)異步請(qǐng)求方法匯總,需要的朋友可以參考下2015-01-01

