Angularは非常に新しいです。私は本当に明白な何かを見逃していると確信しています。
ページにログインフォームがあります。私がしたいのは、ユーザーが正常にログインした後、フォームを非表示にすることです。
私のページ全体が単一のコントローラーを使用しています。
これがHTMLです。同じコントローラー内に実際には他のコンテンツがありますが、ログインフィールド以外のすべてを削除しました。
_<div ng-app="Localizer" ng-controller="StoreListCtrl" ng-init="my_occasion = ''">
<div ng-show="user_signed_in===false">
<div class="row"><h1>Have an account?</h1>
<p>Sign in to quickly access addresses saved to your account</p></div>
<div class="row">
<div class="data">
<input type="username" ng-model="username" name="username" data-placeholder="Username" />
</div>
<div class="data">
<input type="password" ng-model="password" name="password" data-placeholder="Password" />
</div>
<div class="data">
<div class="syo-acctSignBtn yButtonTemplate" ng-click="login_user()">Sign In<div class="btnArrow iconPosition"></div></div>
</div>
</div>
</div>
</div>
_
ユーザーが[サインイン]ボタンをクリックすると、login_user()
という関数が実行されます。これは機能します。ページを手動で更新すると、ログインしていて、非表示にする必要のあるdivが非表示になっていることがわかります。ただし、ページを更新しないと、依存する変数(_user_signed_in
_)が更新されても、divは表示されたままになります。
これが私のコントローラーの_login_user
_関数です。フロントエンドのフィールド検証を含め、多くのものを取り除きました。
_$scope.login_user = function() {
$.post('/site/ajax/login/do_login', {'username': $scope.username, 'password': $scope.password}, function(data) {
if (data.success) {
$window.user_state.status = $window.user_status_key.STATE_SIGNED_IN;
$scope.user_signed_in = $window.user_state.status == $window.user_status_key.STATE_SIGNED_IN;
console.log("user status: " + $window.user_state.status );
console.log("user status key: " + $window.user_status_key.STATE_SIGNED_IN);
console.log("scope.user_signed_in: " + $scope.user_signed_in);
} else {
Modal({
title: "Could not Login",
text: data['errMsg'],
yellow_button: {btn_text: "OK"}
});
}
});
};
_
これは、_console.log
_行の結果です。
ユーザーステータス:サインインユーザーステータスキー:サインインscope.user_signed_in:true
_user_signed_in
_はfalse
と等しくないため、_<div ng-show="user_signed_in===false">
_ div内に表示されるすべてのフォームコンテンツが非表示になると思います。しかし、そうではありません(手動でページを更新しない限り)。何が欠けていますか?
問題は、Angularコンテキストの外で変数(_user_logged_in
_)を更新するため、Angularはそれについて何も知らない(更新するまで)たとえばページ)。
コールバックの本文を$scope.$apply()
でラップする必要があります。
$ apply()は、angular angularフレームワークの外部から式を実行するために使用されます。(たとえば、ブラウザーのDOMイベント、setTimeout、[〜#〜] xhr [〜#〜]またはサードパーティライブラリ)。 angularフレームワークを呼び出しているため、例外処理の適切なスコープライフサイクルを実行し、ウォッチを実行する必要があります。
(私の強調)
ところで、_$http
_サービスを使用してリクエストを実行した場合、同じ問題に直面することはありません。 Angular-context-awareです。
function ShowLoading($scope) {
$scope.loading = true;
setTimeout(function () {
$scope.$apply(function(){
$scope.loading = false;
});
}, 2000);
}