在ajax调用之后,ng-show没有更新的div

Emm*_*myS 11 angularjs ng-show

角度很新; 我确定我错过了一些非常明显的东西.

我的页面上有一个登录表单.我想要发生的是在用户成功登录后隐藏表单.

我的整个页面使用一个控制器.

这是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>
Run Code Online (Sandbox Code Playgroud)

当用户单击"登录"按钮时,会调用一个名为" 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"}
            });
        }
    });

};
Run Code Online (Sandbox Code Playgroud)

这是行的结果console.log:

用户状态:登录用户状态密钥:在scope.user_signed_in中签名:true

由于user_signed_in不相等false,我希望<div ng-show="user_signed_in===false">div中显示的所有表单内容都隐藏起来.但它没有(再次,除非我手动刷新页面.)我错过了什么?

gka*_*pak 24

问题是你user_logged_in在Angular上下文之外更新变量(),因此Angular对它一无所知(例如,在刷新页面之前).

您应该将回调的主体包装在$scope.$apply():

$ apply()用于从角度框架外部以角度执行表达式.(例如,来自浏览器DOM事件,setTimeout,XHR第三方库).因为我们正在调用角度框架,所以我们需要执行异常处理的适当范围生命周期,执行手表.

(强调我的)


顺便说一句,如果您使用该$http服务执行请求,则不会遇到同样的问题,因为它是Angular-context-aware.

  • 关于你的问题"为什么它在Angular上下文之外":对于范围vatiables的赋值不是在控制器中(你似乎相信).而是使用jQuery的`post`方法注册回调函数.然后控制器功能完成执行.一旦jQuery获得响应,它就会更新范围变量,但当时Angular对它一无所知(因此我们必须明确地启动一个摘要周期,以便Angular随模型中的任何更改获得最新信息). (3认同)