角度很新;我确定我错过了一些非常明显的东西。
我的页面上有一个登录表单。我想要发生的是在用户成功登录后隐藏表单。
我的整个页面都使用一个控制器。
这是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。但是,如果不刷新页面,div仍然可见,即使它所依赖的变量(user_signed_in
)确实会更新。
这是我控制器中的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中显示的所有表单内容都隐藏起来。但它没有(再次,除非我手动刷新页面。)我错过了什么?
答案 0 :(得分:24)
问题是您在Angular上下文之外更新变量(user_logged_in
),因此Angular对此一无所知(例如,在刷新页面之前)。
您应该将回调的正文包裹在 $scope.$apply()
中:
$ apply()用于从角度框架外部以角度执行表达式。 (例如,来自浏览器DOM事件,setTimeout, XHR 或第三方库)。因为我们正在调用角度框架,所以我们需要执行异常处理的适当范围生命周期,执行监视。
(强调我的)
$http
服务执行请求,则不会遇到同样的问题,因为它具有Angular-context-aware。
答案 1 :(得分:0)
function ShowLoading($scope) {
$scope.loading = true;
setTimeout(function () {
$scope.$apply(function(){
$scope.loading = false;
});
}, 2000);
}