reload state when you are on same state in angular ui-router - javascript

My Question is can we reload the view in ui-router if you are on same state.
check my code at`http://plnkr.co/edit/MA7CuyH2RFrlaoAgBYog?p=preview
My app.js file is
var app = angular.module('plunker', ['ui.router']);
app.config(function($stateProvider) {
$stateProvider
.state("view1", {
url: "/view1",
templateUrl: "x.html"
})
.state("view2", {
url: "/view2",
templateUrl: "y.html"
})
})
app.controller("MainCtrl",function(){});
And index page is
<body ng-controller="MainCtrl">
Accounts
Dashboard
<div ui-view></div>
Now click on Dashboard link here you will see a text box. fill any value in that. Now again click on Dashboard link. now the state should reload and all data of page should be reloaded including its controller. Please make sure to ui-router only.
Thanks

add attribute to the element with
ui-sref=""ui-sref-opts="{reload:true}"
example:
<a ui-sref-opts="{reload:true}" ui-sref="app.post.applicants">Applicants</a>

Use ng-click and write a controller function with $state.go

You could catch the click in a "ng-click" and use the $state service to transition/reload pragmatically

I had this similar issue and I solved this in two simple way ...
First I wrote a function into related controller (my state was 'inbox' you can use your own ui-state):
$scope.reload = function() {
$state.go('inbox', null, { reload: true });
}
Second call this function to anchor tag:
<a ng-click="reload()">Inbox</a>
Hope it will help. :)

Related

AngularJS UI-Router scroll to top after state change

My page should scroll to top again after i change the page.
I have an angular1.6 page with page transitions & ui-router, so i cant use <div ui-view="main" autoscroll="true"></div>. I tried the following code but its not even executing the console.log :/ :
angular.module("App", ["ngAnimate", "ui.router", "vcRecaptcha"]).run(["$rootScope", "$state", function(a, b) {
a.$on('$stateChangeSuccess',function(){
window.scrollTo(0,0);
console.log("foo");
})
}])
I tried routeChangeSuccess too ... any ideas?
Thanks in advance
If you are using the new ui-router (v1.0.0), the $stateChange* events will not work. You must use $transitions.on* hooks from now on.

Confirm dialog doesn't work properly with link element using ui-sref

Situation:
I am working on an Angular application where in one page manageProviders.html I wanted to add a button to go back to another page providers.html which contains the list of all providers.
I used an <a> element with a ui-sref="providers" attribute, because I use angular states in my application, everything works perfectly.
Problem:
But when I tried to add a confirmation dialog with that button so the user confirms his action, actually it show the confirm dialog but doesn't do anything whether I press OK or Cancel it doesn't work and the link is always active and keeps forwarding me to the Providers.html page.
This is the HTML code of the link with the confirmation code I tried:
<a class="btn btn-default" onclick="return confirm('Are you sure?')" ui-sref="providers">Back</a>
I even tried it with the following code in my controller and deleted the inline onclick event in my link:
$('#goBack').on('click', function(e) {
if (!confirm('Are you sure?')) {
e.preventDefault();
} else {
$('#goBack').attr("ui-sref", "fournisseur");
}
});
Where goBack is the id of my <a> element, but both solutions doesn't work.
This is how I am declaring my states in my application if it helps:
$stateProvider.state('main', {
abstract: true,
templateUrl: 'app/views/main.html',
access: {
requiredLogin: false
}
}).state('addProvider', {
url: APPLICATION_URL + '/addProvider',
templateUrl: 'app/views/content/manageProviders.html',
parent: 'main',
controller: 'providerController'
}).state('providers', {
url: APPLICATION_URL + '/provider',
templateUrl: 'app/views/content/providers.html',
parent: 'main',
controller: 'providerController'
});
EDIT:
I think the problem is related to the ui-sref attribute, because with a simple href and the same confirmation code it works perfectly, like you can see in this fiddle:
<a onclick="return confirm('Are you sure?')" href="www.google.com">Back</a>
How can I achieve it? What am I doing wrong?
Try add directive in a like this
<a ng-click="..()"click></a>
And in js
module.directive('click', function() {
return function(scope, element, attrs) {
$(element).click(function(event) {
if(//){
event.preventDefault();
}else{
//
}
});
}
})
Use ng-click to call controller function
<a ng-click="goBack()">Go back</a>
and in controller, conditionally change ui-router's $state
$scope.goBack = function(){
if(confirm('Are you sure?')){
$state.go('providers');
}
}
Do not forget to inject $state service to your controller
The problem was with the ui-sref attribute, that couldn't be assigned dynamically in the controller in my previous code and for some reasons was always called if it's used in inline HTML.
Solution:
So I found a solution by removing it from my HTML and using $location.path in my controller instead.
This is the controller code updated:
$('#goBack').on('click', function (e) {
if(!confirm('Are you sure?')){
e.preventDefault();
}else{
$location.path(APPLICATION_URL + '/providers');
$scope.$apply();
}
});
And everything works perfectly.
Edit:
I edited my code to use #vohidjon's suggestion with my existing code and used $state.go(), it seems to be the best solution:
$('#goBack').on('click', function (e) {
if(!confirm('Are you sure?')){
e.preventDefault();
}else{
$state.go('providers');
}
});

Angular-ngRoute: force ng-view contents, allow navigation afterwards

While using ngRoute, I want to have Angular configured so that the current contents of ng-view are left as the contents for the current route, and allow the user to navigate away to different routes, rendering their respective templates afterwards:
Plunker
HTML
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view>
<ul>
<li>Some</li>
<li>Soon obliterated</li>
<li>Content</li>
</ul>
</div>
JavaScript
angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/view1', {
templateUrl: 'view1.html',
controller: 'View1Ctrl'
})
.when('/view2', {
templateUrl: 'view2.html',
controller: 'View2Ctrl'
})
.otherwise({
redirectTo: '/view1'
})
})
.controller('View1Ctrl', function() {
})
.controller('View2Ctrl', function() {
});
When the user first sees the page, I want him to see the following:
Note: Angular needs to be bootstrapped at this point, with directives functioning in this area.
Note 2: This content should be in the actual HTML of the page, not in a template or script tag.
Then, when the 'view2' link is clicked:
And then, when the 'view1' link is clicked:
My first thought was using $route.updateParams(newParams) but I think that's not really its purpose.
EDIT
I ended up using
//Server-side rendered code
myModule
.config(['$routeProvider', function($routeProvider){
$routeProvider.when('<# my current route #>',
{
templateUrl: '/server-static',
});
angular.bootstrap(myModule);
In app.js:
myModule
.config('$routeProvider', function($routeProvider){
$routeProvider.when('/my-client-routes',
{
templateUrl: '/my-template.html',
}); // etc.
How can I trick Angular into thinking that the contents of ng-view are the appropiate contents for the current entry route? Can I just cancel route resolution/ngView directive (or make it transclude) rendering for first load? Or if not possible, what's the preferred method to do this?
Thanks
EDIT: See this answer that proposes adding the contents of ng-view to $templateCache through a custom directive.
It's possible for templateUrl to be a function. In which case you can actually change the view based on some kind of state:
var initialized = false;
$routeProvider
.when('/view1', {
templateUrl: function(){
if(initialized){
return 'view1.html';
}
initialized = true;
return 'view-initial.html';
},
controller: 'View1Ctrl'
})
Here is a working Plunker based on yours.
The task you're asking help for can be achieved in a number of ways. #Josh offers a good one. Using $templateCache is another option. But, as you correctly said, these are tricks.
Correct and only recommended approach is to use dedicated template for a default route. You can specify it via external file, via template cache or even script tag, but it's much better, clear and easy to support.
If it's your own code - just choose any preferred way you like. If you want it to be shared with community, used as open-source or enterprise solution - I'd suggest to use the only recommended approach.
Or... look into ui-router )) . May be it's nested views support is the option you need.

AngularJs: Hide navbar element based on route?

I'm trying to figure out how to show or hide an element in my navbar based on the route, or the current view being displayed. For example, I have an basic/advanced toggle button that I put in the navbar (Bootstrap 3) when the user is on the search form. But when they are anywhere else in the app that toggle button should be hidden.
In terms of the DOM, it's just a list item that builds out the nav. I'm not sure if I should show or hide based on a global value that gets set on each view, or if I can just use the route or view name. If so how that would work?
Thanks!
One solution is to build a function in the controller that is responsible for the navbar that could be queried to determine if the element should be displayed:
$scope.isActive = function(viewLocation) {
return viewLocation === $location.path();
};
(The above code uses Angular's $location service)
Then within the template, you can show/hide based on the result of the call (passing in the route that should toggle displaying the element):
ng-show="isActive('/search-form')"
Here's the approach I took with ui-router:
I only want to hide the navbar for a small number of pages so I went with an opt out property on the state(s) that I want to hide the navbar.
.state('photos.show', {
url: '/{photoId}',
views: {
"#" : {
templateUrl: 'app/photos/show/index.html',
controller: 'PhotoController'
}
},
hideNavbar: true
})
Inject $state in your navbar's controller and expose it to the template:
$scope.state = $state;
Then add ng-hide to your navbar template:
<nav ng-hide="state.$current.hideNavbar" ...
Above works perfectly using ui-router don't forget to pass $scope and $state within your function
Example:
app.controller('LoginCtrl', function($scope, $state){
$scope.state = $state;
console.log($state); // this will return the current state object just in case you need to see whats going on for newbies like me :)
});

AngularJs location path change without all controllers resetting

Short version of my question is: How do I change the URL without need to trigger route change or without need to run all the controllers on the currently displayed page?
Details:
I have a template which is displayed inside the <ng-view> that has regions governed by 3 controllers. On the very top of the page I have an interactive map. When you click on the regions it broadcasts a click and other component picks up on it and displays data about this region. Really simple setup.
What I would like to do is allow my users to deep link to the content. So every time someone clicks on a link I'd like to change the URL that can be copied and pasted to another browser. Some other user could just click the link and see the same state the first one saw.
Currently I change the location with code similar to this one:
$scope.$on('mapRegionClick', function($scope, regionCode) {
var url = generateURL(regionCode);
$scope.currentScope.$apply(function(){
$location.path(url);
});});
The URL is then picked up in my routing and the map plus data displays correctly. The downside of this is that every time I click on the map and URL changes the whole template / view is regenerated. Because generating the map is kind of heavy I'd like to trigger only a change to the data presenting controller.
Is it possible? How?
I could do some communication between controllers and achieve the my goal but then I would not be able to do deep linking.
PS: I do not want to use $location.search() and reloadOnSearch=false. my links have to be pretty :)
Sounds like you don't want to use $route service.
The $route service is designed to reload the controllers so that there is no difference between navigating to a URL and refreshing the URL. We do this by doing a full reload on every URL change. This is intentional.
Sounds like your use case, should not be using $route, just $location and ng-include.
You can use $locationChangeStart event to store the previous value in $rootScope or in a service. When you come back, just initialize all the previously stored values from the $rootScope. Check this quick demo using $rootScope.
var app = angular.module("myApp", ["ngRoute"]);
app.controller("tab1Ctrl", function($scope, $rootScope) {
if ($rootScope.savedScopes) {
for (key in $rootScope.savedScopes) {
$scope[key] = $rootScope.savedScopes[key];
}
}
$scope.$on('$locationChangeStart', function(event, next, current) {
$rootScope.savedScopes = {
name: $scope.name,
age: $scope.age
};
});
});
app.controller("tab2Ctrl", function($scope) {
$scope.language = "English";
});
app.config(function($routeProvider) {
$routeProvider
.when("/", {
template: "<h2>Tab1 content</h2>Name: <input ng-model='name'/><br/><br/>Age: <input type='number' ng-model='age' /><h4 style='color: red'>Fill the details and click on Tab2</h4>",
controller: "tab1Ctrl"
})
.when("/tab2", {
template: "<h2>Tab2 content</h2> My language: {{language}}<h4 style='color: red'>Now go back to Tab1</h4>",
controller: "tab2Ctrl"
});
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<body ng-app="myApp">
Tab1
Tab2
<div ng-view></div>
</body>
</html>

Categories

Resources