有角的ui-路由器没有向控制器注入解析。

时间:2021-11-06 12:55:32

I'm just getting started with Angular and Express and facing tough times with it. I come from a java background and want to learn Angular and Express and therefore trying out to build one small application.

我刚开始有棱角,表达,面对艰难的时刻。我来自java背景,我想学习角度和表达,因此尝试构建一个小应用程序。

What I'm trying to do: I have given a password reset link to user so as to change his password. The link is something like:

我想做的是:我给了用户一个密码重置链接,以便修改他的密码。链接是这样的:

localhost:9000/reset/:token

localhost:9000 /重置/:令牌

Now, I have created a simple view which shows an input box to change his password if token is valid otherwise prints an error if token is invalid based on ng-show property of angular.

现在,我已经创建了一个简单的视图,它显示了一个输入框来更改他的密码,如果令牌是有效的,那么如果基于ng-show属性的角度,如果令牌无效,则会打印错误。

Problem: Before I can render my above created view, I want ui-router to check if the :token is valid or not. I will be using the information of validity of token in my controller to control ng-show property mentioned above.

问题:在呈现上面创建的视图之前,我希望ui-router检查:令牌是否有效。我将使用我的控制器中的token的有效性信息来控制上面提到的ng-show属性。

After reading this I tried to leverage the $stateProvider.state functionality with a resolve so as to get the response of validation of token as pre-requisite. This will help me when rendering the actual view where I'm using ng-show technique to show error message or input box to change the password based on the ui-router resolve promiseObject.

读完这篇文章后,我试着利用这个$stateProvider。用一个解决方案来声明功能,以便将验证令牌的响应作为先决条件。这将帮助我在呈现实际视图时,使用ng-show技术显示错误消息或输入框,根据ui-router resolve promiseObject修改密码。

What is the issue now ?

现在的问题是什么?

Well, after breaking my head for too long, I decided to post my question over here. Can anyone please help me here ?

好吧,在伤了我的头太久之后,我决定把我的问题贴在这里。有人能帮我一下吗?

My questions:

我的问题:

1. I'm able to get the data/err from the api call but somehow ui-router is not injecting it in my controller. Can anyone tell me am I doing anything wrong here ?

1。我可以从api调用中获取数据/err,但是ui-router并没有将它注入到我的控制器中。有人能告诉我我在这里做错了什么吗?

2. Right now if the token is not valid, I'm returning a 404 in response from my backend api. But the factory method in frontend takes it as err (Is this expected in Node.js ?) and the err is thrown which results in deferred.reject(). Now, if I go with ui-router definition, if the promise is not resolved then the view won't be rendered, right ? Is there any way by which I can pass this err also to my controller ? Reason why I'm asking to pass err is, my view's ng-show logic is based on the response code (4xx/2xx) depending on which I'll show error message or input box.

2。现在,如果该令牌无效,我将从后端api返回404。但是frontend中的factory方法将其视为err(这是Node中的预期值)。然后抛出err,导致延迟。reject()。现在,如果我使用ui-router定义,如果承诺没有解析,那么视图就不会呈现,对吧?有什么方法可以将err传递给我的控制器吗?我请求传递err的原因是,我的视图的ng-show逻辑基于响应代码(4xx/2xx),这取决于我将显示错误消息或输入框。

Code snippets:

代码片段:

Factory Method which calls the rest api:

调用rest api的工厂方法:

  isPasswordResetTokenValid: function(token, callback) {
    var cb = callback || angular.noop;
    var deferred = $q.defer();

    return User.getUserByPasswordResetToken(token,
      function(data) {
        deferred.resolve(data);
        return cb(data);
      },
      function(err) {
        deferred.reject(err);
        return cb(err);
      }.bind(this)).$promise;
  } 


'use strict';

angular.module('scrubApp')
  .config(function ($stateProvider) {
    $stateProvider
      .state('passwordreset', {
        url: '/reset/:token',
        templateUrl: 'app/account/passwordreset/passwordreset.html',
        resolve: { 

          promiseObj2: function($stateParams, Auth){
              var token = $stateParams.token;
              console.log(token);
               var response = Auth.isPasswordResetTokenValid({token: token})
              .then( function(response) {
                  console.log(response); // shows response
                  if(response.status == 404) {
                    //$scope.token-expiry = true;
                    return response;
                  }
                  if(response.status == 200) {
                    // $scope.user = response.data;
                  }
              })
              .catch( function(err) {
                console.log(err); // shows error
                return err;
              });
          }
        },
        controller: 'ResetPasswordCtrl'  
      });
  });

ResetPasswordCtrl controller:

ResetPasswordCtrl控制器:

'use strict';

angular.module('myApp')
  .controller('ResetPasswordCtrl', function ($scope, User, Auth, Mailer, $stateParams, promiseObj2) {
    $scope.errors = {};
    $scope.user = {};

    console.log(promiseObj2);   // This is coming undefined
    $scope.isTokenExpired = promiseObj2;  // Not able to inject promiseObj2

    $scope.isFormSubmitted = false;


  });

Thanks in advance

谢谢提前

1 个解决方案

#1


2  

Your resolve promiseObj2 should return a promise from promise service, so that your controller will wait till promise gets resolved.

您的解决方案promiseObj2应该从promise service返回一个承诺,以便您的控制器将等待承诺得到解决。

return Auth.isPasswordResetTokenValid({token: token})

Update

更新

If you want to handle some logic on failure of your token request then you could handle it in your promise itself, that can do couple of thing like

如果您想处理令牌请求失败时的一些逻辑,那么您可以在承诺本身中处理它,这可以做一些类似的事情

  1. You could redirected to other page using $state.go('login') or $state.go('error') page.
  2. 您可以使用$state.go('login')或$state.go('error')页面重定向到其他页面。

Code

代码

promiseObj2: function($stateParams, Auth, $state){
  var token = $stateParams.token;
  console.log(token);
  return Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
        $state.go('error')
    }
    if(response.status == 200) {
        return response;
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    return err;
  });
}
  1. If you want to show html page anyhow if error occurs then You could also return data from the .then of promiseObj2 object that will have information about error message. So that error information is return to the controller
  2. 如果你想显示html页面如果发生错误,你也可以返回来自promiseObj2对象的数据,该对象将会有关于错误消息的信息。这个错误信息返回给控制器

Code

代码

promiseObj2: function($stateParams, Auth, $state){
  var token = $stateParams.token;
  console.log(token);
  return Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
      return {status: 404, data: "doen't found resource"}
    }
    if(response.status == 200) {
        return response;
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    return err;
  });
}

Then inside controller we will get resolve the promise of promiseObj2 object and then you will get the value of error in the .then function of it.

然后在控制器内部我们会得到promiseObj2对象的承诺然后你会得到误差值。

angular.module('myApp')
.controller('ResetPasswordCtrl', function ($scope, User, Auth, Mailer, $stateParams, promiseObj2) {
  $scope.errors = {};
  $scope.user = {};
  promiseObj2.then(function(resp){
    console.log(resp)
    $scope.isTokenExpired = resp.isTokenExpired;
  }, function(err){
    console.log(err)
  })
});

Update

更新

If we want to handle a condition where server return 4XX status that means our ajax will call catch function that won't return promise though. We could solve this case by creating custom promise using $q and we will resolve it from the promiseObj2

如果我们想处理服务器返回4XX状态的条件,这意味着我们的ajax将调用catch函数,但不会返回承诺。我们可以通过使用$q创建自定义承诺来解决这个问题,我们将从promiseObj2中解决它

Code

代码

promiseObj2: function($stateParams, Auth, $state, $q){
  var token = $stateParams.token,
      deffered = $q.defer();
  console.log(token);
  Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
      //return {status: 404, data: "doen't found resource"}
      deffered.resolve({status: 404, data: "doen't found resource"});
    }
    if(response.status == 200) {
      //return response;
      deffered.resolve(response);
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    deffered.resolve(err);
  });
  return deffered.promise;
}

#1


2  

Your resolve promiseObj2 should return a promise from promise service, so that your controller will wait till promise gets resolved.

您的解决方案promiseObj2应该从promise service返回一个承诺,以便您的控制器将等待承诺得到解决。

return Auth.isPasswordResetTokenValid({token: token})

Update

更新

If you want to handle some logic on failure of your token request then you could handle it in your promise itself, that can do couple of thing like

如果您想处理令牌请求失败时的一些逻辑,那么您可以在承诺本身中处理它,这可以做一些类似的事情

  1. You could redirected to other page using $state.go('login') or $state.go('error') page.
  2. 您可以使用$state.go('login')或$state.go('error')页面重定向到其他页面。

Code

代码

promiseObj2: function($stateParams, Auth, $state){
  var token = $stateParams.token;
  console.log(token);
  return Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
        $state.go('error')
    }
    if(response.status == 200) {
        return response;
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    return err;
  });
}
  1. If you want to show html page anyhow if error occurs then You could also return data from the .then of promiseObj2 object that will have information about error message. So that error information is return to the controller
  2. 如果你想显示html页面如果发生错误,你也可以返回来自promiseObj2对象的数据,该对象将会有关于错误消息的信息。这个错误信息返回给控制器

Code

代码

promiseObj2: function($stateParams, Auth, $state){
  var token = $stateParams.token;
  console.log(token);
  return Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
      return {status: 404, data: "doen't found resource"}
    }
    if(response.status == 200) {
        return response;
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    return err;
  });
}

Then inside controller we will get resolve the promise of promiseObj2 object and then you will get the value of error in the .then function of it.

然后在控制器内部我们会得到promiseObj2对象的承诺然后你会得到误差值。

angular.module('myApp')
.controller('ResetPasswordCtrl', function ($scope, User, Auth, Mailer, $stateParams, promiseObj2) {
  $scope.errors = {};
  $scope.user = {};
  promiseObj2.then(function(resp){
    console.log(resp)
    $scope.isTokenExpired = resp.isTokenExpired;
  }, function(err){
    console.log(err)
  })
});

Update

更新

If we want to handle a condition where server return 4XX status that means our ajax will call catch function that won't return promise though. We could solve this case by creating custom promise using $q and we will resolve it from the promiseObj2

如果我们想处理服务器返回4XX状态的条件,这意味着我们的ajax将调用catch函数,但不会返回承诺。我们可以通过使用$q创建自定义承诺来解决这个问题,我们将从promiseObj2中解决它

Code

代码

promiseObj2: function($stateParams, Auth, $state, $q){
  var token = $stateParams.token,
      deffered = $q.defer();
  console.log(token);
  Auth.isPasswordResetTokenValid({token: token}) //added return here
  .then( function(response) {
    console.log(response); // shows response
    if(response.status == 404) {
      //return {status: 404, data: "doen't found resource"}
      deffered.resolve({status: 404, data: "doen't found resource"});
    }
    if(response.status == 200) {
      //return response;
      deffered.resolve(response);
    }
  })
  .catch( function(err) {
    console.log(err); // shows error
    deffered.resolve(err);
  });
  return deffered.promise;
}