AngularJS“无法读取未定义的属性'then'”

3

我有一个问题,当我点击登录按钮时,Chrome控制台会记录以下内容:

angular.min.js:117 TypeError: Cannot read property 'then' of undefined at 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;
    }
3个回答

4

您正在返回一个未赋值的变量名为"session"。因此,您在已登录方法中所做的是返回未定义。未定义没有一个叫做 "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方法,该方法反过来返回一个promise。这样你就可以在控制器中使用session了?


我刚刚添加了PHP登录方法。 - faserx
php无关紧要。 - Rob Louie

4
这更多是关于 Promise 误用的问题。
您可能需要先了解一下 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的答案所指出的那样,您应该“返回$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){

  });
};
< p >从 loginService.login().then()返回的response参数正是您先前实现中预期的session变量的值。< /p >

3

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

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

请注意,我已从函数中删除了session变量。应该由控制器中的then函数处理响应。
您的isLoggedlogOut函数已经很好了。只需要重复这个模式即可。

我刚刚添加了PHP登录方法。 - faserx
这个问题与php方法无关。你理解我在答案中说的话了吗? - Snixtor
我意识到了,我只是放置了 PHP 代码,以便让您看到我想从该方法返回什么。 - faserx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接