When I make changes to the template from an sub state and I go to the view again the first loaded (so before the template was updated) view is given.
I have tested it with google chrome. internet explorer, microsoft edge all the same problem.
my state
$stateProvider
.state('games', {
abstract: true,
url: "/?username&token",
templateUrl: "games/views/Games.html",
controller: 'GamesController'
})
.state('games.open', {
url: '',
templateUrl: "games/views/GamesOpen.html"
})
.state('games.active', {
url: "/active",
templateUrl: "games/views/GamesActive.html"
})
HTML
<a ui-sref=".open"><button>open games</button></a>
<a ui-sref=".active"><button>active games</button></a>
<div ui-view></div>
The problem seems to be that the views are cached, the transitions work perfectly only I can't view the updated template and always see the first loaded template that was loaded and never the updated version..
A similair question fixes it by adding ?'+ new Date() at the end of the url but this looks like a hack.
you don't have any url in your game.open state: please check that.i guess that is an issue.
When i was creating an app
i used this code :
(well in my case in my certain app )
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider.state('list',{
url:'/list',
templateUrl:'templates/list.html'
});
$stateProvider.state('edit',{
url: '/edit/:noteId',
templateUrl: 'templates/edit.html',
controller:'EditCtrl'
});
$stateProvider.state('add',{
url: '/add',
templateUrl: 'templates/edit.html',
controller:'AddCtrl'
});
$urlRouterProvider.otherwise('/list');
});
and use
a button like this:
New Note
Related
I have an ionic app with the following ui-router setup, where locations state is the parent of 2 states map and favourites. The updates state is a sort of details page that can be access from any state.
.state('locations', {
abstract: false,
cache: true,
url: '/locations',
templateUrl: 'templates/locations.html',
controller: 'LocationsCtrl'
})
.state('locations.favourites', {
cache: true,
url: '/favourites',
templateUrl: 'templates/locations.favourites.html',
controller: 'LocationsFavouritesCtrl'
})
.state('locations.map', {
cache: true,
url: '/map',
templateUrl: 'templates/locations.map.html',
controller: 'LocationsMapCtrl'
})
.state('updates', {
cache: true,
url: '/updates/:place_id',
templateUrl: 'templates/updates.html',
controller: 'UpdatesCtrl',
params: {'place_id': 'undefined'}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/locations/map');
This is the HTML
<body ng-app="app" animation="slide-left-right-ios7">
<div>
<div>
<ion-nav-bar class="bar-turq">
<ion-nav-back-button class="button-icon icon ion-ios-arrow-back light"></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</div>
</div>
This works perfectly except that the back button on the "updates" state always goes back go locations.map rather than remembering the previous state, ie I might have come from locations.favourites. Is there something fundamentally wrong with my setup?
**
UPDATE:
**
Okay so inside UpdatesCtrl I added this code to check the view history, and no matter where I access the /updates view from, the back view is locations.map
$scope.$on('$ionicView.enter', function() {
console.log($ionicHistory.viewHistory());
}
Remove this params: {'place_id': 'undefined'} or make sure that you pass thru the place_id in $stateparams.place_id
I think that you are ending in an none unknown state (unresolved) and goes to your default state.
You haven't posted your default location route. But I'm assuming that it has this config: $urelRouterProvider.ohterwise('/location.map');
Is there any problem putting default code inside of a <ui-view> element. It appears to work, but I can't find anything saying one way or another if it's okay to use or not.
My current usage is I want the "default" view to be a list of items. Upon clicking one of those items, it switches to an "editor" child state, which replaces the <ui-view> content with the editor child.
Are there any gotchas I should be aware of before continuing with this approach?
Here is an example of what I'm looking at:
routes.js:
.config(($stateProvider) => {
$stateProvider
.state('admin', {
url: '/admin',
templateUrl: 'admin.html'
})
.state('admin.items', {
url: '/admin/items',
templateUrl: 'admin.items.html'
})
});
admin.html:
<ui-view>Default Stuff Here</ui-view>
items.html:
<p ng-repeat="item in items">{{item}}</p>
Now, I know I can do:
.state('admin.default', {
url: '',
templateUrl: 'admin.default.html'
});
And then put that would show in ui-view. However, that needlessly adds a new state and template file, when it seems to work just fine putting the would-be contents of admin.default.html directly into the ui-view of admin.html.
In my case, I'm not talking about a completely stateless option using otherwise(), I'm talking about a defined parent state with a default child state.
We generally do not put anything inside <ui-view></ui-view>, instead we create a default state and use that.
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('about', {
// we'll get to this in a bit
});
});
Here the default one is /home, like that you can create a default one.
First, As said in the other answer, we never give any data within the ui-view.. But while dealing with the ui-router, you should give all the specific states in .config()
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider
.state('home',{
url : '/home',
controller: 'homeCtrl',
templateUrl : 'home.html'
}).state('login',{
url : '/login',
controller: 'loginCtrl',
templateUrl : 'login.html'
});
//AND HERE YOU PROVIDE THE DEFAULT PLACE WHERE THE USER IS TO BE REDIRECTED
//IN CASE OF IMPROPER URL
$urlRouterProvider.otherwise('/login');
});
Secondly, If you want to use the <ui-view></ui-view> to hold some data, you certainly can put some data within them.. But make sure that from the state you define, It should not supply any template or templateUrl. So the data within the <ui-view></ui-view> stays as it is.
And third.. Why to keep a default state..
in case you are defining a state admin in your config(), and then in your admin.routes.js file you can define a state as follows..
.state('admin.login',{
url:'',
controller:'loginCtrl',
templateUrl:'admin.login.html'
});
So in case the url is YOURURL/admin It will directly open the login page by default.. so there is no chance of redundancy...
I followed this example to set up a page with 2 child views.
I have everything in place now, and if I click on the specific link, the subviews are displayed as expected.
Here's my app.js file, in which you can see all of my states:
$stateProvider.state('app',
name: 'app'
url: '/app'
abstract: true
templateUrl: './sections/menu/menu.tpl.html'
).state('app.home',
name: 'home'
url: '/home'
templateUrl: './sections/Home/Home.tpl.html'
).state('app.details',
name: 'appDetails'
url: '/details/:zoneID'
templateUrl: './sections/zoneDetails/zoneDetails.tpl.html'
controller: 'currentZoneFilter'
).state('app.details.overview',
name: 'appDetailsOverview'
url: '/details/:zoneID'
templateUrl: './sections/zoneDetails/zoneDetailsOverview.tpl.html'
).state('app.details.edit',
name: 'appDetailsEdit'
url: '/details/edit/:zoneID'
templateUrl: './sections/zoneDetails/zoneDetailsEdit.tpl.html'
).state('app.setup',
name: 'setup'
url: '/setup'
templateUrl: './sections/setup/setup.tpl.html'
).state 'app.about',
name: 'about'
url: '/about'
templateUrl: './sections/about/about.tpl.html'
controller: 'info'
$urlRouterProvider.otherwise 'app/home'
as you can see, I have app.details, app.details.overview, app.details.edit.
app.details is the parent, and here's the page code:
This it the parent page
<a ui-sref="app.details.edit">Show edit</a>
<a ui-sref="app.details.overview">Show overview</a>
<div ui-view></div>
If I click on the link, the right template and page section is displayed. My question here is: How can I have Overview loaded by default when I reach this page?
I had a look at $urlRouterProvider.when, that I think that .when is good if you have a different URL.
My URL should be details/:zoneID for the page with overview template loaded and details/edit/:zoneID when the edit template is loaded, so I think that .when is not a good approach. Any help? thanks
You have to use the rule function of $urlRouterProvider.
$urlRouterProvider.rule(function ($injector, $location) {
// check if the location is the desired location then move to the //new location.
});
At the end, I finally solved this.
I changed state URLs for app.details / app.details.overview / app.details.edit like this:
.state('app.details',
name: 'appDetails'
url: '/:zoneID'
templateUrl: './sections/zoneDetails/zoneDetails.tpl.html'
controller: 'currentZoneFilter'
.state('app.details.overview',
name: 'appDetailsOverview'
url: '/details'
templateUrl: './sections/zoneDetails/zoneDetailsOverview.tpl.html'
.state('app.details.edit',
name: 'appDetailsEdit'
url: '/edit/day:day'
templateUrl: './sections/zoneDetails/zoneDetailsEdit.tpl.html'
so that now the URL starts with the zoneID and then it appends the details or edit to display the right template.
Here are a couple way. Check https://github.com/angular-ui/ui-router/wiki for implementation details.
Listen for the $StateChangeStart event. If this matches your state, perform a redirect. Be sure to execute event.preventDefault() to cancel current route change.
Add a controller to your parent state, it will check the $state.current value and if the value match his state will redirect to the child (this is what i have in my application).
EDIT : as requested in comment :
if($state.current.name != 'app.details'){
$state.go('app.details.overview');
}
I'm having trouble with a simple ui-router sample I have set up. I have a company page, whose default sub-state should show CompanyProfile, but it defaults to nothing until I click profile. Once I clicked employees, I have to click profile twice to get it to show again. Ideally I want ui-sref="company()" and ui-sref="company.profile()" to display the same screens. It seems like I'm missing something small..
Here's the plnkr:
http://plnkr.co/edit/A3LHGqQIuRlK1QdjuzrP?p=preview
HTML:
<a ui-sref="company()">company</a>
| <a ui-sref="company.profile()">profile</a>
| <a ui-sref="company.employees()">employees</a>
JS:
$stateProvider
.state('company', {
url: '/',
templateUrl: 'company.html',
controller: 'CompanyCtrl as CompanyCtrl'
})
.state('company.profile', {
url: '',
templateUrl: 'profile.html',
controller: 'CompanyProfileCtrl as CompanyProfileCtrl'
})
.state('company.employees', {
url: '/employees',
templateUrl: 'employees.html',
controller: 'CompanyEmployeesCtrl as CompanyEmployeesCtrl'
});
btw, I'm writing everything as components and decided to define the routes in each component, so you'll find the 3 state definitions in the 3 controllers. I'm not entirely sure this is the best approach or not yet.
The default state is entirely dependent on how you call $urlRouterProvider.otherwise(), passing it a url transitions the application to the particular url, wherein ui-router detects and looks for the very first state it sees.
In your main.js configuration, defines the / url as the default url for the application, which is technically the company state's url and is the very first state in the chain of parent states and children states, making it the default state. This in fact, is also the resulting url for the company.profile state that you wanted your application to default to.
To solve this problem, depends on the use cases for your application.
Use case: If your application defines the company state as a non-navigational state, then setting it to an abstract state solves the problem.
DEMO
CompanyCtrl.js
$stateProvider
.state('company', {
abstract: true,
url: '/',
templateUrl: 'company.html',
controller: 'CompanyCtrl as CompanyCtrl'
});
Use case: If the company state is nagivational, then simply remove the url definition in the company state and change the url defintion for the company.profile state to '/'. The only caveat for this solution would be the loss of the href attribute to be applied for for any anchor tags defined with the ui-sref="company" state which also implies the application of the text cursor. To mitigate this problem you might as well define all anchor tags with ui-sref attribute with a pointer cursor.
DEMO
CompanyCtrl.js
$stateProvider
.state('company', {
templateUrl: 'company.html',
controller: 'CompanyCtrl as CompanyCtrl'
});
CompanyProfileCtrl.js
$stateProvider
.state('company.profile', {
url: '/',
templateUrl: 'profile.html',
controller: 'CompanyProfileCtrl as CompanyProfileCtrl'
})
style.css
a[ui-sref] {
cursor: pointer;
}
UPDATE:
Use Case: The same with use case #2 but making the company state an abstract state.
DEMO
CompanyCtrl.js
$stateProvider
.state('company', {
abstract: true,
templateUrl: 'company.html',
controller: 'CompanyCtrl as CompanyCtrl'
});
We are new to AngularJS and finding one-or-two problems with setting up multiple routes when using ID's from Json Data.
We are trying to replicate AngularJS Tutorial, so we can click each 'View' button to display a more detailed page of the selected 'Warranty Item' same as the tutorial.
We have uploaded our AngularJS problem to Plunker, If anyone can see something we're missing or know a better route to go down please let us know.
App.js State with ResultSet.JobID
.state('home.singleWarranty', {
url: '/singlewarranty/{resultset.JobID}',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
There is a working/updated plunker
Because there are these states
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: 'homeController'
})
.state('home.singleWarranty', {
url: '/singleWarranty/:jobID',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
We need to build the url like this
View
Instead of this original
// View
The point is that state 'home.singleWarranty' inherits/extends the url from its parent. So we have to include the parents '/home' as well.
Other solution:
In case we would like to start the url in a child state from the begining, we can do it like this
.state('home.singleWarranty', {
url: '^/singleWarranty/:jobID',
See the ^ at the url begining. Then even this would work:
View
Check the updated plunker here