I'm new in AngularJS Community and I'm developping my first app with this Framework.
I created a new controller with this code :
.controller('AccountCtrl', function($scope, $location) {
alert('test');
})
And my route :
.state('app.account', {
url: "/account",
views: {
'menuContent': {
templateUrl: "templates/account.html",
controller: 'AccountCtrl'
}
}
})
The alert popup is shown the first time I access to the controller. But, if I change URL and I come back to AccountCtrl (with a classic html a), the alert popup is not shown again.
Could somebody explain to me why ?
Thanx for your help !
In Ionic Framework views and controllers will be cached by default. You ma add a listener to the views scope to receive a notification when the view is re-active again. For more information see: http://ionicframework.com/docs/api/directive/ionView/
and http://ionicframework.com/docs/api/directive/ionNavView/
You may also disable the cache on a view <ion-view cache-view="false">
.controller('AccountCtrl', function($scope, $location) {
$scope.$on('$ionicView.beforeEnter', function () {
// update campaigns everytime the view becomes active
// (on first time added to DOM and after the view becomes active after cached
alert('test');
});
})`
to reload Controller each time in ui router, use reload: true option on the .state
$stateProvider
.state('app.account', {
url: "/account",
reload: true //forcefully reload route and load controller again
})
Related
Hi guys am a beginner in mean stack development I have tried to refresh the page after logout.I have tried location.reload(); but it doesn't work tell me the possible code for page reload in this scenario
$rootScope.$on('$routeChangeStart', function (event) {
var storage = userService.isLoggedIn();
console.log(storage);
if (!storage) {
console.log('DENY');
$rootScope.adminlogin = "adminlogin";
console.log($rootScope.adminlogin);
$location.path('/login');
$route.reload();
// $state.go('/login', null, {reload: true});
}
else {
console.log('ALLOW');
$rootScope.admindashboard = "admindashboard";
var path = $location.path();
console.log(path);
console.log(storage);
if(path == '/login'){
$location.path('/');
}
}
});
You should use $window.location.reload() from the the $window service if you want to refresh the page. It does the same thing as the reload button in your browser.
The reason you should use the $window service instead of directly accessing the native window object as per the AngularJS documentation:
While window is globally available in JavaScript, it causes
testability problems, because it is a global variable. In AngularJS we
always refer to it through the $window service, so it may be
overridden, removed or mocked for testing.
On a side note as you stated you are using the $route service, just calling $route.reload() will only reload your controllers and not your entire application.
All you need to do is this little line of Vanilia JS:
document.location.href=document.location.href
EDIT: why is this getting downvoted?
if you are using routes, then on click of Logout just route it to your login page.
Snap shot from demo:
these are my routes:
$routeProvider
.when('/login', {
controller: 'LoginController',
templateUrl: 'modules/authentication/views/login.html',
hideMenus: true
})
.when('/', {
controller: 'HomeController',
templateUrl: 'modules/home/views/home.html'
})
.otherwise({ redirectTo: '/login' });
and when i click on 'Logout' on my page it should do somehting like:
<p>Logout</a></p>
it should redirect to login page as per routes.
I want to temporarily change the browser url when the ui bootstrap modal is opened ( The page behind should remain as is, only the url changes ). When the modal is closed the url should be reverted back to the original one.
Steps :
User loads the page
url : xyz.com/home
User clicks a link opens a modal
url : xyz.com/detail/123
possible solution : changing url with html5 push state
problem : Angular ui-router tries to run its routes as per the changed url, eventually changing the background page.
User closes the modal
url : xyz.com/home
possible solution : html5 pop state
problem : Reloads the background page, which kills the purpose
Example implementation : Pinterest pins and their pin details popup.
You can use ui-router-extras sticky state to solve your problem. There is simple example with modal by the link. You should create two named views, one for main content (background) and one for modal.
<div ui-view="app"></div>
<div ui-view="modal"></div>
Mark the state, from what you want to access to modal as sticky: true in route definition.
.state('main', {
abstract: true,
url: '/',
templateUrl: '_layout.html'
})
.state('main.index', {
url: '',
sticky: true,
views: {
'app': {
templateUrl: 'index.html'
}
}
})
.state('main.login', {
url: 'login/',
views: {
'modal': {
templateUrl: 'login.html'
}
}
})
Also add an event for stateChangeSuccess:
$rootScope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
if ((from.views && !from.views.modal) || !from.views) {
$rootScope.from = from;
$rootScope.fromParams = fromParams;
}
});
so, when you need to close modal, you can just
$state.go($rootScope.from, $rootScope.fromParams);
There is small problem for that solution. If you reload page on the modal state, then the app ui-view will be empty.
This can be achieved by having a nested state and triggering the modal using onEnter callback:
$stateProvider
.state('contacts', {
url: '/home',
templateUrl: 'home.html',
controller: function($scope, MyService){
$scope.contacts = MyService.getContacts();
}
})
.state('contacts.details', {
url: "^/details/:id", // using the absolute url to not have the "/home" prepended
onEnter: function($state, $uibModal) {
var modal = $uibModal.open({
templateUrl: 'details.html',
controller: function($scope, $stateParams, MyService) {
// get data from service by url parameter
$scope.contact = MyService.getContact($stateParams.id);
}
});
modal.result.finally(function() {
$state.go('^'); // activate the parent state when modal is closed or dismissed
});
}
});
This technique is described in the ui-router's FAQ.
Here the plunk. In this example the modal's scope is created as a child of the $rootScope - the default $uibModal's behavior when no scope is passed to it. In this case we should use the service in the modal's controller to obtain the data by url parameter.
To have master and details URLs look like these - xyz.com/home and xyz.com/detail/123 - we should use the absolute URL (^/details/:id) in the child state.
Using this solution you can open the detail URLs directly and still have both, master and detail states, activated properly, so sharing the detail URL is possible.
I think you can achive that with ngSilent module
https://github.com/garakh/ngSilent
using $ngSilentLocation.silent('/new/path/');
(once you open modal and again after closing it)
Managed to implement this using https://github.com/christopherthielen/ui-router-extras/tree/gh-pages/example/stickymodal
Below is my partial angularJS code which implements routeprovider
TicketApp.config(function ($routeProvider) {
$routeProvider
// route for Create Ticket Page
.when('/CreateTicket', {
templateUrl: '../Ticket/Create',
controller: 'CreateCtrl'
})
// route for Open Ticket Page
.when('/OpenTickets', {
templateUrl: '../Ticket/MyTickets',
controller: 'MyTicketsCtrl'
})
// route for All Users Search Page
.when('/SearchUsers', {
templateUrl: '../Account/AllUsers',
controller: 'AllUsersCtrl'
})
..........
When user clicks SAME link more than once, only the
first click makes an AJAX request ,the subsequent requests
do not.
What needs to be modified so that subsequent requests to SAME link also make an AJAX call.
EDIT :
I also added below code
TicketApp.run(function ($rootScope, $templateCache, $location) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
$templateCache.remove(current.templateUrl);
});
});
did not work for me.. :(
Why do want to execute Ajax requests? It is only one request required to load the template from the server. There is no need to load it multiple time, because it shouldn't change or your architecture is not really compliant to Angular.
You could probably invalidate the templateCache and force Angular to reload the templates.
Might be this will work for your case .When the user will click the Button(the ajax call start's) you just hide it(button) once the AJAX call return a response back then show it(button).
My scenario entails a route with a controller and view for state app.foo. When a user lands on this route via a menu-link, I would like UI-Router to always rerun/execute the controller -- as I have an event being dispatched here to get data from another module. The problem is that if User switches to app.bar and comes back to app.foo, this event never fires.
How can I force UI-Router to run this controller again?
Example:
.state('app.foo', {
url: '/foo',
alwaysReload: true
});
Is this possible?
This is default behavior if you add a controller to the route definition, for ex:
$stateProvider.state('app.foo', {
url: '/foo',
views: {
"main": {
controller: function ($scope) {
console.log('foo controller loaded.');
},
controllerAs: 'foo',
templateUrl: 'foo/foo.tpl.html'
}
}
'foo controller loaded.' will always log when the 'app.foo' state is loaded.
I'm making a single page application (SPA). I made a controller called InitialControler to load the data from the server at this url (local.app/init).
I want this url to be opened before any other url. I'm using ui-router, I did a $state.go('init') in the .run() function but it still load the requested page before the 'init' page
First create state called app
$stateProvider.state('app', {
abstract: true,
templateUrl: "assets/partials/container.html",
controller: 'AppCtrl',
resolve: {
init: function(MyFactory) {
return MyFactory.resolver();
}
}
});
Now, any new state you create should be child state of app state. This is also good because it become sort of your root scope. And state will not process unless your factory resolves.
This is how you create your factory
app.factory('MyFactory', function($http){
var items = [];
return {
resolver: function(){
return $http.get('my/api').success(function(data){
items = data;
})
},
get() {
return items;
}
}
});
Now in any other state
$stateProvider.state('app.items', {
url: '/items',
templateUrl: "assets/partials/items.html",
controller: function($scope, MyFactory){
$scope.items = MyFactory.get();
}
});
More on sate resolve
https://github.com/angular-ui/ui-router/wiki#resolve
If you are using ui-router then you could resolve this using nested states. For example:
$stateProvider
.state("main", {
url: "/",
template: '<div ui-view></div>',
controller: 'InitController'
})
.state("main.landing", {
url: "landing",
templateUrl: "modules/home/views/landing.html",
controller: 'LandingPageController'
})
.state("main.profile", {
url: "profile",
templateUrl: "modules/home/views/profile.html",
controller: 'ProfileController'
});
In this example you have defined 3 routes: "/", "/landing", "/profile"
So, InitController (related to "/" route) gets called always, even if the user enters directly at /landing or /profile
Important: Don't forget to include <div ui-view></div> to enable the child states controller load on this section
One way to do is, in config declare only 'init' state. And in InitialController, after data is loaded(resolve function of service call), configure other states. But in this approach, whenever you refresh the page, the url will change to local.app.init.
To stay in that particular state even after reloading, the solution I found is to have a StartUp app in which I loaded the required data and after that I bootstraped the main app manually by angular.bootstrap.