在$ http之前调用时,angularjs变量不显示

时间:2013-10-04 10:14:54

标签: javascript angularjs

在我的角度应用程序中,我有一个消息服务来显示我的应用程序的信息,加载和错误消息。它看起来像是:

module.factory('msgSvc', function(){
    var current_message = '';

    return {
        message: function(){
            return current_message;
       },
       setMessage: function(msg){
            console.log('setting message: '+ msg);
            current_message = msg;
        },
        clear: function(){ current_message = null; current_style = null}
    }
});

在我看来我有

<span class="pull-left label label-warning" >{{ msg.message() }}</span>

我有一个登录控制器,当用户提交表格时,我希望在发送ajax登录时显示“登录你...”消息。如果有错误,则显示错误消息。这是我的代码:

function LoginCtrl($scope, $http, msgSvc) {
   [...]
   $scope.login = function(creds) {
    console.log(creds);
    msgSvc.setMessage('Logging in...');

    $http.post('http://...',creds)
        .success(function(data){
            console.log(data);
            [...]
            msgSvc.clear();
            $location.path('/');

        })
        .error(function(data, status){
           console.log(status);
            msgSvc.setMessage('Wrong username or password.');

        });

   };
}

login()由提交表单调用,即使调用该函数(它出现在控制台中),Logging in...也不会显示。但会出现错误消息。

我做错了什么?

编辑:登录表单

<form class="form">
    <input type="text" placeholder="Username" ng-model="loginCreds.username" required />
    <input type="password" placeholder="Password" ng-model="loginCreds.password" required />
   <button ng-click="login(loginCreds)">Login</button>
</form>

编辑2 如果它发生了任何变化,那么在服务和实际代码中有许多控制器设置消息,显示消息的控制器(设置$scope.msg变量的地方)与设置消息的控制器不同。

function BodyCtrl($scope, msgSvc) {
    $scope.msg = msgSvc;
}

3 个答案:

答案 0 :(得分:1)

您的实施存在几个问题:

  1. 由于消息是在私有变量中设置的,因此您需要使用$watch来显示消息;
  2. .factory是单身,因此setMessage会为所有控制器设置相同的消息。
  3. 最简单的解决方案是将控制器的$scope传递给svcMsg

    app.factory("msgSvc", function () {
      return function (scope) {
        var priv_scope = scope;
    
        this.setMessage = function (msg) {
          console.log('setting message: '+ msg);
          priv_scope.message = msg;
        };
    
        this.clear = function () {
          priv_scope.message = "";
        };
    
      };
    });
    

    在你的控制器中,你会这样做:

    var msg = new msgSvc($scope);
    

    如果您执行想要将邮件传播到所有控制器,请使用$rootScope

    app.service("msgSvc", function ($rootScope) {
        var priv_scope = $rootScope;
    
        this.setMessage = function (msg) {
          console.log('setting message: '+ msg);
          priv_scope.message = msg;
        };
    
        this.clear = function () {
          priv_scope.message = "";
        };
    });
    

    使用$rootScope检查此Plunker:
    http://plnkr.co/edit/NYEABNvjrk8diNTwc3pP?p=preview

    由于$ rootScope实际上是Angular中的全局变量,所以不应该滥用它。如果您不小心在控制器中设置$scope.message,也可能会出现问题。另一种方法是使用$watch来检测message

    的更改
    // In your controller, do:
    $scope.$watch(
      function () {
        return msgSvc.message;
      },
      function () {
        $scope.message = msgSvc.message;
      }
    )
    

    以下是使用$watch的示例:
    http://plnkr.co/edit/vDV2mf?p=info

答案 1 :(得分:0)

在要在视图上显示值的每个位置设置$scope.msg

function LoginCtrl($scope, $http, msgSvc) {
   [...]
   $scope.msg = "";
   $scope.login = function(creds) {
    console.log(creds);
    $scope.msg = msgSvc.setMessage('Logging in...');

    $http.post('http://...',creds)
        .success(function(data){
            console.log(data);
            [...]
            $scope.msg = msgSvc.clear();
            $location.path('/');

        })
        .error(function(data, status){
           console.log(status);
            $scope.msg = msgSvc.setMessage('Wrong username or password.');

        });

   };
}

我知道你可能试图避免这种情况,但其价值的变化并没有被传播。

答案 2 :(得分:-1)

在错误()

中添加$ apply
  function LoginCtrl($scope, $http, msgSvc) {
             [...]

        $scope.login = function(creds) {
        console.log(creds);

        msgSvc.setMessage('Logging in...');
        $scope.msg = msgSvc;



       $http.post('http://...',creds)
              .success(function(data){
                 console.log(data);
                 [...]
                 msgSvc.clear();
                 $location.path('/');
               })
              .error(function(data, status){
                   $scope.$apply(function() {
                      msgSvc.setMessage('Wrong username or password.');
                   });
            });
      };
   }

DEMO