For some reason I cannot redirect to the next state.
genAPISettings.view.html only contains:
<div ui-view></div>
The controller only contains this:
app.controller('AdminDashboardGeneralAPISettingsController', ['$scope',
'$state', 'llApi', function ($scope, $state, llApi) {
}]);
The state:
.state('dashboardContainer.GeneralAPISettings', {
url: 'GeneralAPISettings',
templateUrl: 'views/AdminDashboard/genAPISettings/genAPISettings.view.html',
controller: 'AdminDashboardGeneralAPISettingsController'
}
Using $state.go("dashboardContainer.GeneralAPISettings", {}); only shows me a flash of redirecting to the state, but then quickly redirects me to the precious state. Using <a ui-sref = "dashboardContainer.GeneralAPISettings">General API</a> does not redirect the page at all. However, changing the url manually to /GeneralAPISettings does correctly change to this state.
You might have an ui-sref on the container, causing that sref to trigger instead of the one that you wanted.
For example, if your code was like this:
<div ui-sref="state1"><a ui-sref"state2">Link</a></div>
When clicking on the Link, you might expect to go to state2, but instead go to state1.
Source: I've encountered a similar problem.
Related
I debated a while on this but I got a Plunk that reproduce it.
I have a state "Contact" that get loaded by default. with $state.transitionTo
Inside that state I have some views, they all get loaded and everything work.
If I click to change the state to "Home" by default or by "ui-sref" and in the "Home" state/template I have ui-sref="contacts". When we click back to set the state to contacts it should work, but all the sub views are now not being called properly.
It seems that when ui-sref call the state this one behave differently that when it is loaded by default.
Why $state.transitionTo(''); seems to work differently than ui-sref.
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /
$urlRouterProvider.otherwise("/")
$stateProvider
.state('home', {
templateUrl: 'home.html',
controller: function($scope){
}
})
.state('contacts', {
templateUrl: 'contacts.html',
controller: function($scope){
}
})
.state('contacts.list', {
views:{
"":{
template: '<h1>Contact.List Working wi no Data defined.</h1>'
},
"stateSubView":{
template: '<h2>StateSubView Working</h2>'
},
"absolute#":{
template: '<h2>Absolute item</h2>'
}
}
});
});
myapp.controller('MainCtrl', function ($state) {
$state.transitionTo('contacts.list');
})
Q2:
Why is the Absolute tag that is under contact work when I add the view in the Index, but is not working when it is inside the contact.html file. Absolute reference work only with the Index and not if called everywhere?
"absolute#":{
template: '<h2>Absolute item</h2>'
}
I saw that in index.html you have an empty ui-view tag. What do you expect to go there? I think you can not do this. The router just doesn't know with which state (home or contacts) it should replace. Apparently it picks the second one (contacts). I'd suggest to put url: '/' in the home state and you'll see the difference.
This is for sure one issue.
Other than that:
You can't simply access views from contacts.list in contacts afaik.
The empty ui-view work as a wild card and can be use to switch across multiple route even if we have nested element. But if we have a nested view contact.list it can only be access if we put the whole path in ui-sref="contacts.list" because the list child of contact cannot be access only by using ui-sref="contacts"
I have a text box with a search Button as below
On clicking the search button, I am calling SearchController.search method and
my expectation is it will display a new page with the result.
$scope.search = function () {
$http.get('data/results.json').success(function (data) {
$scope.activities = data;
$state.go('results',data);
});
and my app.js looks as below
var myApp = angular.module('MyApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('results', {
url: '/results',
templateUrl: 'result.html',
controller: 'SearchController'
});
$urlRouterProvider.otherwise('/');
});
But when I click on search button, nothing happens and url only changes to l/#/results .
I am not having any ui-view in search page and I want to go results page to display the result. How to get this fixed? what is the mistake I am doing?
You can't send a not mapped object into $state.go.
Looking the API: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state
Another similar problem: AngularJS: Pass an object into a state using ui-router
If you want to display it on a different page, use the "ui-sref" on the html to navigate to the new page and call ng-init on the page e.g
<button type="button" ui-sref="results">
and on result.html, you can call the init on the parent node such as
<section ng-init="search()">
.....
....
</section>
and your controller will look like this now
$scope.search = function () {
$http.get('data/results.json').success(function (data) {
$scope.activities = data;
});
With ui-router, state changes happens and different view is displayed based on state. So , when ui-router is used , moving from one page to another page is a wrong perception . We move from one state to another state and hence parameter passing can be done using "services".
In this plunk you have two ui-router states, a parent and a child. When the child is invoked by clicking on the link, since it has the option reload: true it is always reloaded. This is fine, but the problem is that the parent state is reloaded as well. Try to click on the 'Populate 11' link several times and you'll see that the parent timestamp also changes.
How can I reload only the child?
Javascript:
var app = angular.module("app", ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('state1', {
templateUrl: 'state1.html',
controller: function($scope) {
$scope.theTime1 = Date.now();
}
})
.state('state1.state11', {
templateUrl: 'state11.html',
controller: function($scope) {
$scope.theTime11 = Date.now();
}
});
});
It's actually very simple.
Don't use reload because that does exactly what you found. It reloads everything for the route.
Instead, add a parameter to your child route and every time the link is clicked make sure to change that parameter. That will force the child state to be reloaded.
I updated your plunk with an example. I just added a num parameter and increase a count variable each time the link is clicked.
http://plnkr.co/edit/qTA39rrYFYUegzuFbWnc?p=preview
A changing parameter as Mathew Foscarini suggested, is (for sure) way to go. There could be also another solution, technique with state reloader. Below, and in this updated plunker we can see simplified version, but we can even pass some params there to make it more general
.state('state1.reloader', {
controller: function($state) {
$state.go('state1.state11')
}
})
And we can call it like:
// instead of this
<a href="#" ui-sref="state1.state11" ui-sref-opts="{reload: true}">
// we can do this
<a href="#" ui-sref="state1.reloader" >
Check it here
I created a plunkr for this code and it can be viewed here:
The problem is very simple. I am trying to create a master/details scenario. So there are two templates: listings and details. In the listing controller there is a methods redirects to the detials route. This method works well as i verified it with the debugger (via breaking point).
$scope.goToDetails = function(propItem) {
//$rootScope.currentProperty = propItem;
$location.path('/details/');
}
The 'details' path (see blow) calls the 'detailsController', which is currently (for testing purposes) defined as:
var detailsController = function($scope, $http, $routeParams, $rootScope) {
var dosomething = "do";
};
I verified with the debugger that the execution indeed reaches the "dosomething" command and that the route changes in the browser to "details". However, and HERE is the problem, when I continue with the debugger, angular changes the route back to the default route. I went over the definitions but nothing that i did seems wrong.Any ideas?
Here is how I defined the routes:
app.config(function($routeProvider) {
$routeProvider
.when('/main/', routes.main)
.when('/details/', routes.details)
.otherwise({
redirectTo: '/main'
});
});
var routes = {
main: {
templateUrl: 'PropertiesResults.html',
controller: 'listingController'
},
details: {
templateUrl: 'property-detail.html',
controller: 'detailsController'
},
}
Replace:
<a href="#" ng-click="goToDetails(property)" ...
With:
<a href="" ng-click="goToDetails(property)" ...
Or it will go to your otherwise route.
Change your link to be
Read More
A few things to consider:
Links should work just like in a regular html page
If you want to execute code on a new page, look into putting that code on the route, or in a controller in the new view.
If you want to conditionally enable or disable the link, think about disabling the link with something like <a ng-disabled="expression"... this might not work out of the box but you could add a custom directive.
If you still need to run that code in a controller method, consider using a <button type="button" class="link"... and style it to look like a link, e.g. display: inline; border: 0; background: transparent;"
Happy coding
If I have a one level route, then the hash links work as expected with no rerouting. However I have some urls that are country/kh and if I try using hash tags such as country/kh#projects, the page reroutes, which is very annoying.
So, if im on page countries and click the link #developing, then the page will scroll to #developing without rerouting, which is desired. If I'm on page country/kh and I click #projects, the page will reroute, then scroll to #projects; I don't want the rerouting to occur.
The issue only occurs for links of the nature page1/parameter#anchor, not for simple pageA#anchor.
It is very difficult to answer your question without any code samples or a plunker. I implemented a plunker code ( http://plnkr.co/edit/oflB21?p=preview ) to try to reproduce this issue but as you can see I could not reproduce the issue. i.e. You can easily navigate back and forth between two different sections of the page, e.g. between #/Country/Italy#Section-4 and #/Country/Italy#Section-1, without any page load or reroute. Please check out my working example at the following plunker. This most probably is happening to you due to a missing hash bang or forward slash or details like that.
HTML snippet for the home page:
<ul>
<li>Go to /Country</li>
<li>Go to /Country/US</li>
<li>Go to /Country/Italy#Section-4</li>
<li>Go to /Country/Canada#Section-8</li>
</ul>
HTML snippet for the country page:
<div id="Section-1" class="section pink">
Section 1
<div ng-if="country">
<a ng-href="#/Country/{{country}}#Section-8">Go to /Country/{{country}}#Section-8</a>
</div>
<div ng-if="!country">
<a ng-href="#/Country#Section-8">Go to /Country#Section-8</a>
</div>
</div>
All the JavaScript code:
var app = angular.module("app", ["ngRoute"]);
app.config(["$routeProvider", "$locationProvider",
function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: "./home-page.html",
caseInsensitiveMatch: true,
})
.when("/Home", {
templateUrl: "./home-page.html",
caseInsensitiveMatch: true,
})
.when("/Country", {
templateUrl: "./country-page.html",
caseInsensitiveMatch: true,
})
.when("/Country/:country", {
templateUrl: "./country-page.html",
caseInsensitiveMatch: true,
})
}]);
countryController.$inject = ["$scope", "$routeParams", "$location", "$anchorScroll"];
function countryController($scope, $routeParams, $location, $anchorScroll) {
$scope.country = $routeParams.country;
if (!!$location.$$hash) {
$location.hash($location.$$hash);
$anchorScroll();
}
}
Alright, I believe the main issue is that Angular handles routing with hashes (sometimes). What you need to do is use the $anchorScroll service. So your JS would look something like:
function ScrollCtrl($scope, $location, $anchorScroll) {
$scope.gotoBottom = function (){
// set the location.hash to the id of
// the element you wish to scroll to.
$location.hash('bottom');
// call $anchorScroll()
$anchorScroll();
};
}
And then your HTML could be:
<div id="scrollArea" ng-controller="ScrollCtrl">
<a ng-click="gotoBottom()">Go to bottom</a>
<a id="bottom"></a> You're at the bottom!
</div>
http://plnkr.co/edit/De6bBrkHpojgAbEvHszu?p=preview - this is a plunkr (not mine) that demonstrates using $anchorScroll if you need to see it in action
There's a dead-simply solution to your problem...
Instead of doing:
go
Just do
go
I suspect the reason for the unexpected behavior is a bug/feature of whatever routing solution you are using (ie the built-in angular router, or ui-router or whatever). ui-router has a way to disable re-routing when going to the same route...
I think I had the same problem that you are having.
This is how I did it with my github page, http://ngmap.github.io.
Th site, http://ngmap.github.io, has many pages and each page has lots of anchors, all anchors are coded naturally.
Without the following code of http://ngmap.github.io/javascripts/app.js, when you click an anchor in your page;
it sets $location.path to /anchor. i.el http://url.com/#anchor
and it sets $location.hash to ``.
This behaviour will prevent the page from scrolling down to the hash because simply there is no hash in the url.
By simply adding $location.hash and scrolling down to that anchor, all should work.
/**
* when the location is changed, scroll the page to the proper element.
* by changing location hash from '' to 'hash', so that it can be used as $anchorScroll
*/
$rootScope.$on('$locationChangeSuccess', function(newRoute, oldRoute) {
$location.hash($location.path().replace(/^\//,""));
$anchorScroll();
});
With the above code,
$location.path remains the same, /anchor
$location.hash now becomes anchor
The only thing you may not like is, the url. It looks little dirty, but I did not mind.
i.e. http:/ngmap.github.io/basics.html#/map-geolocation#map-geolocation
Hope it helps