使用 ui-router in AngularJS 获取数据并将其传递到另一个状态
Getting data and passing it to another state with ui-router in AngularJS
我知道这里讨论了在控制器之间传递数据的话题,但我对这个看似常见的问题有点困惑,我想知道是否有人对这种类型有 'best practice'用例。
场景是当用户单击 link 或提交表单时调用服务以通过其 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?';
}
})
}
}
工厂returns一个$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
])
})();
在状态 'rsvp-enter' 中,通过从 RsvpService 检索 Rsvp.guests 属性 将记录设置到范围。
var RsvpEnterController = function($state, RsvpService){
var reCtrl = this;
reCtrl.guests = RsvpService.guests
}
对于一个简单的问题,这感觉像是一种非常迂回的处理方式,而且我觉得我可能滥用了 promises 并在我的代码中引入了很多不好的做法。例如,错误处理是在服务中进行的,而控制器中的响应实际上是在进行错误处理。这肯定是错误的?我很好奇是否有人对使用 angularjs 和 ui-router 的这种类型的用例有任何见解,并且对如何让它变得更好有任何建议?预先感谢您的帮助。
根据标题,您可能应该查看 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 访问。
我认为将路由逻辑移到控制器中会更好。因此,服务 RsvpService
将更像一个数据控制器或数据模态,仅适用于 Rsvp
。您甚至可以添加 setter 功能和更新功能。
更好的是,在 RsvpService
中,您可以检查变量 Rsvp
是否为空,如果不是,则 return 它而不是再次获取。
//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;
}]);
对于更复杂的情况,您可以查看下面的 link,这里有一篇好文章:http://www.webdeveasy.com/angularjs-data-model/
我知道这里讨论了在控制器之间传递数据的话题,但我对这个看似常见的问题有点困惑,我想知道是否有人对这种类型有 'best practice'用例。
场景是当用户单击 link 或提交表单时调用服务以通过其 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?';
}
})
}
}
工厂returns一个$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
])
})();
在状态 'rsvp-enter' 中,通过从 RsvpService 检索 Rsvp.guests 属性 将记录设置到范围。
var RsvpEnterController = function($state, RsvpService){
var reCtrl = this;
reCtrl.guests = RsvpService.guests
}
对于一个简单的问题,这感觉像是一种非常迂回的处理方式,而且我觉得我可能滥用了 promises 并在我的代码中引入了很多不好的做法。例如,错误处理是在服务中进行的,而控制器中的响应实际上是在进行错误处理。这肯定是错误的?我很好奇是否有人对使用 angularjs 和 ui-router 的这种类型的用例有任何见解,并且对如何让它变得更好有任何建议?预先感谢您的帮助。
根据标题,您可能应该查看 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 访问。
我认为将路由逻辑移到控制器中会更好。因此,服务 RsvpService
将更像一个数据控制器或数据模态,仅适用于 Rsvp
。您甚至可以添加 setter 功能和更新功能。
更好的是,在 RsvpService
中,您可以检查变量 Rsvp
是否为空,如果不是,则 return 它而不是再次获取。
//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;
}]);
对于更复杂的情况,您可以查看下面的 link,这里有一篇好文章:http://www.webdeveasy.com/angularjs-data-model/