在控制器中更改AngularJS中的ng样式值

时间:2017-05-22 10:47:28

标签: javascript html css angularjs

我有一个登录表单,带有提交按钮。单击该按钮时,将调用RESTful Web服务。如果登录成功,则会将用户重定向到另一个页面。如果不是,则应显示带有错误消息的范围。

我尝试使用ng-style来操作显示错误的跨度的css。

这是我的span元素:

<span id="login-error-msg" class="login-error" ng-style="errorMsg">*Wrong Username/Password</span>

在控制器中我有以下几行:

$scope.errorMsg = { "display" : "none"};

如果我收到服务器的回复,说明登录并不成功。我这样做:

$scope.errorMsg = { "display": "block" };

但是,没有任何变化,span元素仍然隐藏。但是,当我再次单击提交按钮时。风格变化,跨度可见。

我该如何解决这个问题?在我看来,在更改$ scope.errorMsg的值之前渲染了span。

更新:我按照建议使用ng-show。 这是我的范围:

<span id="login-error-msg" class="login-error" ng-show="displayError">*Wrong Username/Password</span>

而且,在我设置的控制器中:$scope.displayError = false;

最后,当我收到服务器的回复时。我这样做:

$scope.displayError = true;

但是,我仍然遇到同样的问题。如果我输入两次错误的数据,我只会看到更改。一种解决方案可能是重新加载页面,但这似乎是不必要的。

更新2:以下是控制器的完整代码:

myApp.controller('loginController', function($scope, $rootScope, $http, $location, $timeout, SERVER_PATH) {

        $scope.displayError = false;

    $scope.login = function(){

                var username = $scope.username;
                var password = $scope.password;

                var url =  SERVER_PATH + "login/doLogin";

                var jsonObj = JSON.stringify({phoneNumber:username, password:password});

                $.blockUI({ message: '<h1><img src="images/squares.gif" /> Logging in...</h1>' });

                $http.post(url, jsonObj)
                .then(function successCallback(response) {

                        console.log(JSON.stringify(response.data));

                        var jsonResponse = JSON.parse(JSON.stringify(response.data)); 
                        console.log("JSON response status: " + jsonResponse.status);

                        if (jsonResponse.status == 0) {
                        // Login success
                        setTimeout($.unblockUI, 2000);
                        $rootScope.token = jsonResponse.token;
                        console.log("Login success. Token: " + jsonResponse.token);
                        $timeout(function() { $scope.$apply(function() { $location.path("/sign"); }); }, 2000);
                }    

                else {        
                        setTimeout(function() {
                                $.unblockUI();
                                $scope.displayError = true;
                               // $scope.errorMsg = { "display": "block" };
                        }, 2000);

                }

        }, function errorCallback(response) {
                        // called asynchronously if an error occurs
                        // or server returns response with an error status.
                        console.log("An error has occured while sending the data to the server...");
                        setTimeout($.unblockUI, 2000);
                });


};

})

更新3:我通过将DamTime Rashidi建议的setTimeout更改为$ timeout来解决了这个问题。

现在我的身体看起来像这样:

$timeout(function(){
                        $.unblockUI();
                        $scope.displayError = true; 
                   }, 2000);

1 个答案:

答案 0 :(得分:2)

听起来您的摘要周期在第一次点击后没有运行。这取决于您的异步调用的处理方式(角度自己的$http方法在完成后触发摘要周期。)

如果在异步操作完成后添加$scope.$apply(),如果没有其余代码的上下文,则可能会有效。

编辑:是的,setTimeout正在弄乱它。 Angular无法理解在超时回调中检查范围的变化。您可以使用$timeout(callback, ms)或手动使用$scope.$apply。如果您使用$timeout,请确保将其注入您的控制器。