Angular. Ui-router and access rights to the template
Connected the Ui-router. Displays three different templates in different locations. We send a certain parameter (aka stateParams) to the server, which returns true
or false
. How do I add this check and where to go, so that the result from the server displays the necessary templates or outputs a template with information about the unavailability of the template? If false
all three templates should be unavailable.
I tried to solve it head-on by writing a check in templateUrl, it doesn't work and duplicate it for 3 templates clearly not correct.
.config(['$locationProvider','$stateProvider', function($locationProvider,$stateProvider,$http){
$stateProvider
.state('page', {
url: "/page:page",
views: {
"viewVideo": {
templateUrl: function (stateParams){
$http({
url: basePath + '/lesson/GetPageData',
method: "POST",
data: $.param({order: stateParams.page}),
})
.success(function (response) {
if(response) return '/index_'+ stateParams.page+'_video.html'
})
},
controller: 'lessonPageCtrl'
},
"viewText": {
templateUrl: function (stateParams){
$http({
url: basePath + '/lesson/GetPageData',
method: "POST",
data: $.param({order: stateParams.page}),
})
.success(function (response) {
if(response) return '/index_'+ stateParams.page+'_text.html'
})
},
controller: 'lessonPageCtrl'
},
"viewQuiz": {
templateUrl: function (stateParams){
$http({
url: basePath + '/lesson/GetPageData',
method: "POST",
data: $.param({order: stateParams.page}),
})
.success(function (response) {
if(response) return '/index_'+ stateParams.page+'_quiz.html'
})
},
controller: 'lessonPageCtrl'
}
}
})
}]);
I wanted to use solutions to the problem in this way
angular
.module('lessonApp')
.run([
'$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$on('$stateChangeStart',
function (event, toState, toParams, fromState, fromParams) {
if (true) {
event.preventDefault();
}
}
);
}
]);
But I have no idea how to push an ajax request through $http into if
. Who will show a simple example with Resolve for my problem? Before loading the template, you need to check what the $http ajax request returns
Http://plnkr.co/edit/oILOiXh8iGxoxzT1Xe2j?p=preview
Another question arose. To reduce the load on the server, the data will be extracted from the model PageData, which will be initialized when the page is first loaded:
angular
.module('lessonApp')
.run([
'$rootScope', '$state', '$stateParams','$http',
function ($rootScope, $state, $stateParams, $http) {
$http({
url: basePath + '/lesson/GetPageData',
method: "POST",
data: $.param({lecture: idLecture}),
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'}
})
.success(function (response) {
$rootScope.pageData = response;
})
Then, so as not to contact the server when changing the link every time(except in cases when the model will change) I would like to check some value from this model. If for example $rootScope.pageData[0].isDone==true
we load the template
templateUrl: function (stateParams){
if ($rootScope.pageData[0].isDone==true)
return '/video.html'
},
Is this also solved via resolve, or is there something more elementary? And then $rootScope
can't be used in $stateProvider
1 answers
You can use the resolve property.
This property is an object containing key-value pairs.:
Key - {string}: name of the dependency to be implemented in the controller.
value - {string|function}:
- if the string is an alias for the service.
- if a function - the function value will be embedded. If the function returns Promise, it will be resolved before the controller is created, and the value will be embedded in the controller. If the returned Promise changes to the status rejected, the event
$stateChangeError
By subscribing to this event and checking the error, you can perform the necessary processing actions.
For your case: $http
the service returns Promise, so it can be moved to the resolve
.state('page', {
url: "/page:page",
resolve: {
auth: function($q, $http){
return $http({
url: basePath + '/lesson/GetPageData',
method: "POST",
data: $.param({order: stateParams.page}),
})
.success(function (response) {
if(response) return "authorized";
return $q.reject('not authorized');
});
}
},
....
Now, in the case when the query returns true everything will appear and if you write in controller
function lessonPageCtrl(auth, .../*другие внедрения $scope и т.д.*/) {
console.log(auth); //authorized
If the request returns false, we transfer the result to the state rejected and catch it in the handler $stateChangeError
$rootScope.$on('$stateChangeError',
function(event, toState, toParams, fromState, fromParams, error) {
console.log(error); // not authorized
}
);
Usage example
Example with $http, in data.json - value.
Remark
You assign the same controller to three different view, in this case, three controller objects will be created, which they will be unrelated.