Я знаю, что тема передачи данных между контроллерами обсуждалась здесь, но я немного смутился о том, что похоже на общую проблему, и мне было интересно, есть ли у кого-то "лучшая практика" для такого типа использования.
Сценарий - это когда пользователь нажимает ссылку или отправляет форму, которая вызывает службу, чтобы получить объект по его идентификатору. Если объект найден, состояние изменяется и объект возвращается контроллеру нового состояния. Если объект не найден, возвращается ошибка, то есть "мы не можем найти эту запись".
В приведенном ниже примере электронное письмо передается контроллеру через форму и отправляется в "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 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 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 no record found, server returns a 404 error
return err.status;
});
}
return Rsvp;
}
angular.module('mainApp')
.factory('RsvpService', [
'$http',
'$state',
RsvpService
])
})();
В состоянии "rsvp-enter" запись устанавливается в область видимости, получая свойство Rsvp.guests из RsvpService.
var RsvpEnterController = function($state, RsvpService){
var reCtrl = this;
reCtrl.guests = RsvpService.guests
}
Это похоже на очень окольный способ сделать что-то для простой проблемы, и я чувствую, что я, вероятно, злоупотребляю обещаниями и внедряю много плохой практики в свой код. Например, обработка ошибок выполняется в службе, и ответ в контроллере действительно выполняет обработку ошибок. Неужели это неправильно? Мне было просто любопытно, есть ли у кого-нибудь представление об этом типе использования с угловыми и ui-маршрутизаторами и какие-либо предложения о том, как сделать его лучше? Заранее спасибо за вашу помощь.
Я думаю, было бы лучше переместить логику маршрутизации в контроллер. Таким образом, служба 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 no record found, server returns a 404 error
return err.status;
});
}
return Rsvp;
}]);
Для более сложной ситуации вы можете посмотреть ссылку ниже, хорошую статью здесь: http://www.webdeveasy.com/angularjs-data-model/
Из названия вы должны, вероятно, посмотреть на параметры, например:
.state('home', {
params: {
email: null
}
})
Доступ через $ state.params.email, например. Чтобы пройти через $ state.go, вы бы сделали что-то вроде $ state.go('another.page', {email: $ email_value});
Или данные:
.state('home', {
data: {
email: null
}
})
Доступ через $ state.current.data.email например.