【问题标题】:AngularJS 'Cannot read property 'then' of undefined'AngularJS'无法读取未定义的属性'then''
【发布时间】:2016-10-23 15:38:41
【问题描述】:

我有这个问题,当我点击登录按钮时,chrome 控制台会记录这个:

angular.min.js:117 TypeError: Cannot read property 'then' of undefined 在 m.$scope.logIn (loginModuleController.js:11)

服务:

angular.module('loginModule')
.factory('loginService', function($http){
  return{
    login: function(username, password){
      var session;
      $http.post('../server/php/auth/auth.php', {
        username: username,
        password: password
      })
      .then(function(res){
        session = res;
      });
      return session;
    },
    isLogged: function(){
      return $http.get('../angCMS/server/php/auth.php?is_logged=true');
    },
    logOut: function(){
      return $http.get('../angCMS/server/php/auth.php?logout=true');
    }
  };
});

控制器:

angular.module('loginModule')
.controller('LoginCtrl', ['$scope', 'loginService', function($scope, loginService){

  $scope.auth = false;

  $scope.username;
  $scope.password;
  $scope.logIn = function(){
    loginService.login($scope.username, $scope.password).then(function(response){

    }, function(res){

    });
  };

  $scope.isLogged = function(){
    loginService.isLogged()
    .then(function(response){
      if(response){
        $scope.auth = true;
      }
    });
  };

  $scope.logOut = function(){
    loginService.logOut()
    .then(function(response){
      if(response){
        $scope.auth = false;
      }
    });
  };

}]);

这是html模板:

<div class="container" ng-if="auth==false">
  <div class="col-md-4 col-md-offset-4">
    <div class="row">
      <br/><h2 align="center">Login</h2>
    </div>
    <div class="well">
        <form class="form-horizontal">
        <fieldset>
          <div class="form-group">
                <input type="text" class="form-control" placeholder="Username" ng-model="username" required>
          </div>
          <div class="form-group">
                <input type="password"  class="form-control" placeholder="Password" ng-model="password" required>
          </div>
          <div class="form-group">
                <button class="btn btn-md btn-primary btn-block" type="submit" ng-click="logIn()">Sign in</button>
          </div>
        </fieldset>
      </div>
    </form>
  </div>
</div>

PHP登录方式:

public function login($user, $pass){

        $user = htmlspecialchars(trim($user));
        $pass = md5(htmlspecialchars(trim($pass)));

        $res = $this->DB->prepare("SELECT * FROM `admin` WHERE username = :user");
        if(!$res->execute(Array(":user"=>$user)))
            die(mysql_error());

        $row = $res->fetch(PDO::FETCH_ASSOC);

        if(!$row['password'] == $pass)
            die("Errore: password errata!");

        $_SESSION['logged'] = $row;
        array_push($session, $_SESSION['logged'], true);

        return $session;
    }

【问题讨论】:

    标签: javascript php angularjs


    【解决方案1】:

    这更像是一个滥用承诺的问题。

    您可能想先看看 Promise 是如何工作的:

    来自您的服务代码:

    login: function(username, password){
      var session;
      $http.post('../server/php/auth/auth.php', {
        username: username,
        password: password
      })
      .then(function(res){
        session = res;
      });
      return session;
    }
    

    当调用login(username, password) 时,返回时会话仍然是undefined

    这是因为$http.post() 是一个异步函数,.then() 子句不会立即执行。

    正如Snixtor's answer所指出的, 你应该“返回$http.post()的返回值”:

    login: function(username, password){
      return $http.post('../server/php/auth/auth.php', {
        username: username,
        password: password
      });
    }
    

    然后参考你的控制器的logIn方法:

    $scope.logIn = function(){
      loginService.login($scope.username, $scope.password).then(function(response){
        // response === 'session' 
      }, function(res){
    
      });
    };
    

    loginService.login().then() 中的 response 参数正是您之前实现中预期的 session 变量的值。

    【讨论】:

      【解决方案2】:

      您正在返回一个名为“session”的未分配变量。因此,您在登录方法中所做的是返回未定义。 Undefined 没有调用 then 的方法。

      login: function(username, password){
            var session;
            $http.post('../server/php/auth/auth.php', {
              username: username,
              password: password
            })
            .then(function(res){
              session = res;
            });
            return session;
          },
      

      我的猜测是您实际上想要返回 $http.post 方法,该方法又返回一个承诺。这样就可以在控制器中使用会话了?

      【讨论】:

      • 我刚刚添加了php登录方式
      • php无关。
      【解决方案3】:

      您的服务函数login 未能返回调用$http.post 创建的承诺。相反,你需要这个:

      login: function(username, password){
        return $http.post('../server/php/auth/auth.php', {
          username: username,
          password: password
        });
      }
      

      还要注意,我已经从函数中删除了 session 变量。控制器中的 then 函数需要处理响应。

      您的isLoggedlogOut 函数看起来已经不错了。只需重复该模式即可。

      【讨论】:

      • 我刚刚添加了php登录方式
      • 问题与php方法无关。你明白我在回答中所说的话吗?
      • 我意识到了,我放php只是为了让你看到我想从方法中返回什么
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 2016-06-18
      • 1970-01-01
      • 2015-03-28
      • 2018-02-04
      • 1970-01-01
      相关资源
      最近更新 更多