使用AngularJS中的ui-router获取数据并将其传递到另一个状态

时间:2016-04-19 09:13:47

标签: angularjs angularjs-scope angular-ui-router singleton angularjs-service

我知道在这里讨论了在控制器之间传递数据的主题,但是我对一些常见的问题感到有点困惑,我想知道是否有人有过最佳实践&#39 ;对于这种用例。

该方案是用户单击链接或提交调用服务的表单以通过其ID获取对象。如果找到该对象,则更改状态并将对象返回到新状态的控制器。如果找不到该对象,则会返回错误,即“我们无法找到该记录”。

在下面的示例中,电子邮件通过表单传递给控制器​​并发送给' RsvpService':

var MainController = function($state, $http, GuestListService, RsvpService){

    var mnCtrl = this;
    mnCtrl.submitEmail = submitEmail;

    function submitEmail(email){

        mnCtrl.error = "";
        mnCtrl.emailEntry = "";

        RsvpService.getGuestsByEmail(email)
        .then(function(res){
            //if an error comes back and it's 404, set an error message
            if(res === 404){
                mnCtrl.error = 'We can\'t find you :( Sure you got the right email?';
            }
        })
    }   
}

工厂返回$ http.post ...

(function(){
'use strict';

var RsvpService = function($http, $state){

    var Rsvp = {};

    Rsvp.getGuestsByEmail = function(email){
        return $http.post('/getGuestsByEmail', {email : email})
        .then(function(res){
            //if there's a record, set it to Rsvp.guests and redirect to the next state
            Rsvp.guests = res.data;
            $state.go('rsvp-enter');
        }).catch(function(err){
            //if there's no record found, server returns a 404 error
            return err.status;
        });
    }

    return Rsvp;

}

angular.module('mainApp')
.factory('RsvpService', [
    '$http',
    '$state',
    RsvpService
])

})();

在州&rs; rsvp-enter'通过从RsvpService检索Rsvp.guests属性将记录设置为范围。

var RsvpEnterController = function($state, RsvpService){

    var reCtrl = this;
    reCtrl.guests = RsvpService.guests
}

对于一个简单的问题,这感觉就像是一种非常迂回的做事方式,我觉得我可能会滥用承诺并在我的代码中引入很多不良做法。例如,错误处理正在服务中完成,控制器中的响应实际上正在进行错误处理。当然这是错的?我很好奇是否有人对angularjs和ui-router的这种用例有任何见解,并且对如何使其更好有任何建议?在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

从标题中,您应该查看params,例如:

.state('home', {
  params: {
    email: null
  }
})

例如通过$ state.params.email访问。要通过$ state.go,你会做一些像$ state.go(' another.page',{email:$ email_value});

data

.state('home', {
  data: {
    email: null
  }
})

例如通过$ state.current.data.email访问。

答案 1 :(得分:0)

我认为将路由逻辑移到控制器中会更好。因此,服务RsvpService将更像是Rsvp的数据控制器或数据模式。您甚至可以添加setter功能和更新功能。

更好的是,在RsvpService内你可以检查变量Rsvp是否为空,如果不是,则返回它而不是再次取回。

//a simple example
angular.module('mainApp')
    .factory('RsvpService', ['$http', '$state', '$q',
        function($http, $state, $q){

            var Rsvp = {};

            Rsvp.getGuestsByEmail = function(email) {
                //if the guests is already fetched
                if(Rsvp.guests) {
                   var deferred = $q.defer();
                   deferred.resolve(Rsvp.guests); 
                   return deferred.promise;
                }

                //call loadGuestsByEmail() function and chain the promise object
                return Rsvp.loadGuestsByEmail(email);
            };

            Rsvp.loadGuestsByEmail = function(email) {
                return $http.post('/getGuestsByEmail', {email : email})
            .then(function(res){

                Rsvp.guests = res.data;

            }).catch(function(err){
            //if there's no record found, server returns a 404 error
                return err.status;
            });
        }

        return Rsvp;

}]);

对于更复杂的情况,您可以查看下面的链接,这里有一篇好文章:http://www.webdeveasy.com/angularjs-data-model/