У меня возникают проблемы с добавлением новых состояний на этапе выполнения моего приложения с помощью «UI-Router-Extras».
Я уже довольно давно пытаюсь подключить и загрузить новые состояния ПОСЛЕ того, как пользователь успешно прошел аутентификацию с помощью плагина 'UI-Router-Extras' 'ui-router-extras'
Вот ссылка на примеры UI-Router-Extras для документацию FutureState, которую я использую, но я чувствую, что, возможно, мой сценарий немного отличается от того, что показано, или я вообще что-то упускаю.
ПРИМЕР КОДА В PLUNKER — НАЖМИТЕ КНОПКУ ВХОД -> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy
Код ниже загружается и работает:
Мне удалось лениво загрузить исходный файл app.config() из внешнего файла. Как код описан ниже:
PUBLIC — внешние изначально загруженные маршруты с использованием "UI-Router-Extras" — "lazyload/states/public-states.json"
[
{
"name": "unauth",
"url": "/",
"controller": "LoginCtrl",
"templateUrl": "app/components/core/login/login.html",
"roles": ["public"]
},
{
"name": "otherwise",
"url": "/",
"roles": ["public"]
}
]
Первоначальная загрузка приложения — успешная ленивая загрузка общедоступных состояний, начиная с входа в систему:
'use strict';
var app = angular.module('app', ['ui.router', 'ct.ui.router.extras'])
.config(function ($urlRouterProvider, $stateProvider, $futureStateProvider) {
app.stateProvider = $stateProvider; // MIGHT NEED REFERNCE LATER?
app.futurestateProvider = $futureStateProvider; // MIGHT NEED REFERNCE LATER?
// ASYNC LOAD OF ROUTES AVAILABLE - SOON TO BE BY ROLE
var futureStateResolve = ["$http", function($http) {
return $http.get("lazyload/states/public-states.json").then(function(response) {
angular.forEach(response.data, function(state) {
$stateProvider.state(state);
console.log(state.roles);
})
})
}];
$futureStateProvider.addResolve(futureStateResolve);
console.log($futureStateProvider);
});
Код ниже НЕ работает
Ниже мой код для той части, которая не работает:
PRIVATE – внешние изначально загруженные маршруты с использованием "UI-Router-Extras" – "lazyload/states/public-states.json"
Этот json ниже предназначен для добавления после входа пользователя в систему с использованием отложенной загрузки и FutureStates. Пока не повезло :(
[
{
"name": "app",
"abstract": true,
"url": "?menu1State",
"templateUrl": "app/components/core/layout/layout.html",
"controller": "LayoutCtrl",
"roles": ["level1"]
},
{
"name": "app.dashboard",
"url": "/app",
"views": {
"feature": {
"templateUrl": "app/components/core/features/features.html",
"controller": "FeatureCtrl"
}
},
"roles": ["level1"]
},
{
"name": "app.associations_beanbags",
"url": "/app/associations/bean-bags?myParam1&myParam2&modalState",
"views": {
"feature": {
"templateUrl": "app/components/core/features/associations/bean-bags.html",
"controller": "BeanbagsCtrl"
}
},
"roles": ["level2"]
}
]
Кнопка входа в систему, запускающая ленивое создание состояний после успешной аутентификации:
<a id="btn-fblogin" href="" class="btn btn-primary pull-right" ng-click="callNotify(username, password);">Login</a>
Что происходит, когда пользователь нажимает кнопку входа в систему, он имитирует успех и вызывает «$scope.callNotify», запуская код, который вы видите ниже. В итоге все работает до тех пор, пока не появится 'app.futurestateProvider.futureState(newState);' и попытка вызвать новое состояние, чтобы узнать, было ли добавлено '$state.go( 'app.dashboard');'. Все это приводит к ошибке, которая гласит следующее:
Ошибка консоли:
Error: Could not resolve 'app.dashboard' from state 'unauth'
at Object.transitionTo (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2521:17)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:136:34)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:874:55)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:1301:48)
at Object.go (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2454:21)
at http://localhost:3000/app/components/core/auth/auth-service.js:58:13
at http://localhost:3000/bower_components/angular/angular.js:8113:11
at wrappedCallback (http://localhost:3000/bower_components/angular/angular.js:11573:81)
at wrappedCallback (http://localhost:3000/bower_components/angular/angular.js:11573:81)
at http://localhost:3000/bower_components/angular/angular.js:11659:26
Для меня это похоже на то, что состояния никогда не добавлялись, когда мы ожидали, что приводит к ошибке, говорящей что-то вроде «Извините, я не вижу маршрут, который вы ищете».
'use strict';
app.controller('AuthServiceTestCtrl', ['$window','$scope','$http', '$state', function (win, $scope, $http, $state) {
$scope.callNotify = function(username,password, $stateProvider, $futureStateProvider) {
//notify(username, password); // CALL SERVICE AND GET A RETURN VALUE / ACTION
var loadedAgain = $http.get("lazyload/states/private-states.json").success(function(response) {
if(username == "[email protected]" && password == "abc123"){
console.log('Valid Credentials. Logging In.');
// NOW THAT USER IS LOGGED IN REGISTER NEW PRIVATE ROUTE / STATES - PREFERABLY FROM THE SECURED SERVER FILE ('private-states.json') ABOVE
var adminModuleFutureStates = [
{
"name": "app",
"abstract": true,
"url": "?menu1State",
"templateUrl": "app/components/core/layout/layout.html",
"controller": "LayoutCtrl",
"roles": ["level1"]
},
{
"name": "app.dashboard",
"url": "/app",
"views": {
"feature": {
"templateUrl": "app/components/core/features/features.html",
"controller": "FeatureCtrl"
}
},
"roles": ["level1"]
},
{
"name": "app.associations_bean-bags",
"url": "/app/associations/bean-bags?myParam1&myParam2&modalState",
"views": {
"feature": {
"templateUrl": "app/components/core/features/associations/bean-bags.html",
"controller": "BeanBagsCtrl"
}
},
"roles": ["level2"]
}
];
angular.forEach(adminModuleFutureStates, function(newState) {
console.log(newState);
app.futurestateProvider.futureState(newState); // WAS SAVED AS A VAR IN APP CONFIG FOR LATER REFERENCE
});
// FINALLY GO TO ONE OF THE NEWLY ADDED PRIVATE STATES WE JUST ADDED WHICH IS A DASHBOARD
$state.go('app.dashboard');
}
});
};
}]);
Мне очень жаль, что у меня нет готового рабочего примера, я сейчас на нем, но я решил опубликовать это сейчас, чтобы показать, что у меня есть, и, возможно, получить обсуждение или решение о том, как я могу загружать состояния к ui-router во время выполнения через мой контроллер, указанный выше, после того, как приложение уже загрузило конфигурацию и т. д.
В конечном итоге я пытаюсь сделать следующее:
Мне действительно нужно открыть только два безопасных общедоступных маршрута для начала при входе в систему. Затем, когда пользователь входит в систему, предыдущие общедоступные маршруты остаются, и я пытаюсь добавить или украсить существующие маршруты новыми, которые теперь позволяют пользователю иметь доступ только к маршрутам, которые предоставляет его роль. Безопасность для нас чрезвычайно важна, и я не вижу никакой выгоды в загрузке всех возможных маршрутов заранее на странице входа, чтобы кто-то знал, что такое API или маршруты сервера, по крайней мере, не входя в систему.
Я очень извиняюсь за бессвязность, но я пришел к выводу, что я просто делаю это неправильно, и мне нужны дополнительные глаза, чтобы, возможно, понять, почему я не могу добавлять новые состояния после загрузки.
Серьезно! Большое спасибо!
ПРИМЕР КОДА В PLUNKER — НАЖМИТЕ КНОПКУ ВХОД -> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy