I'm using UI-Router module for routing. I have 2 states that router should match the urls with them according to nested routes laws :
// Dashboard
.state('dashboard', {
url: "/dashboard",
templateUrl: "dashboard/views/index.html",
controller: "DashboardController",
...
})
// Users
.state('users', {
url: "/users",
templateUrl: "users/views/index.html",
controller: "UsersController",
...
})
// Single User
.state('users.id', {
url: "/{id:(?:[a-z0-9_-]{3,16})}",
templateUrl: "users/views/show.html",
controller: "UserController",
...
})
also I have set a default route :
$urlRouterProvider.otherwise("/dashboard");
Problem :
when I go to http://127.0.0.1:8000/app/#/users/testuser123, it shows index.html from users state instead of show.html from users.id state. What's the Problem ?
You should add users within your url definition for users.id if you call http://127.0.0.1:8000/app/#/users/testuser123
.state('users.id', {
url: "/users/{id:(?:[a-z0-9_-]{3,16})}",
templateUrl: "users/views/show.html",
controller: "UserController",
...
})
Related
I have an Ionic app that uses ng-token-auth. It uses 2 ng-token-auth configs for 2 sets of users with different authentication apis.
app.js
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'templates/home/home.html',
controller: 'HomeCtrl'
})
.state('employee', {
url: "/employee",
templateUrl: "templates/employee.html",
controller: 'EmployeeCtrl'
})
.state('employer', {
url: "/employer",
templateUrl: "templates/employer.html",
controller: 'EmployerCtrl'
})
$urlRouterProvider.otherwise('/home');
HomeCtrl
$scope.$on('$ionicView.beforeEnter', function(){});
I currently put the authentication checking in a $ionicView.beforeEnter but it flashes the home screen and then redirects to the correct page. Is there a better place to put this. Thanks
U can use "resolve" from the state-provider..
edit => employer-state to home-state
.state('home', {
url: "/home",
templateUrl: "templates/home/home.html",
controller: 'HomeCtrl',
resolve: {
//check if user is remembered & redirect to next state
}
})
This should be simple but I just can't figure it out.
I have two routes:
$stateProvider
.state('users', {
url: '/users',
views: {'#': {
templateUrl: 'templates/users.tpl.html',
controller: 'UsersCtrl as users'
}}
})
.state('users.edit', {
url: '/{userId}',
views: {'#': {
templateUrl: 'templates/editUser.tpl.html',
controller: 'EditUserCtrl as editUser'
}}
});
This works fine if you use a ui-sref or $state.go to navigate to the "users" state by name, but if you type domain.com/users/ into the URL bar it goes to the edit state with empty userId parameter even though there is nothing after the trailing stash.
Normally this wouldn't be a problem but firing the editUser route with no userId causes console errors which would be a pain to fix.
Is this easily fixable?
Take a look to this post:
https://github.com/angular-ui/ui-router/issues/50
and this link referenced in the post:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-make-a-trailing-slash-optional-for-all-routes
Your states definition should be
$stateProvider
.state('users', {
url: '/users',
views: {'#': {
templateUrl: 'templates/users.tpl.html',
controller: 'UsersCtrl as users'
}}
})
.state('users.edit', {
url: '/edit/{userId}',
views: {'#': {
templateUrl: 'templates/editUser.tpl.html',
controller: 'EditUserCtrl as editUser'
}}
});
your child state url should be '/edit/{userId}'. When we create a child state its url automatically added its parent state url. So if your url is '/{userId}' it will be 'domain.com/users/{userId}'. That's why for domain.com/users/ its navigate to the state users.edit with null parameter value.
https://github.com/angular-ui/ui-router/wiki/nested-states-%26-nested-views
I have this in my app.js:
$stateProvider
.state('actionplans', {
url: "/actionplans",
templateUrl: "pages/actionplans.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
})
How can I default load nest view action 'actionplans.summary.html' when called actionplans.html?
There is a working example
The way which will
load some view inside of a parent - and stay on parent
allow child change it when navigating to child
is called Multiple named views:
.state('actionplans', {
url: "/actionplans",
views: {
'': {
templateUrl: "pages/actionplans.html",
//controller : 'ActionplansCtrl'
},
'#actionplans': {
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
}
}
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
//controller : 'ActionplansCtrl'
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
//controller : 'ActionplansCtrl'
})
What we did above, is that we used views : {} object to define two views. First is targeting the index.html (the '') the second is targeting this state view target for children ( the '#actionplans').
views: {
'': { // index.html
...
},
'#actionplans': { // this targets the unnamed view for children
Read more about absolute names here
Another way, is to define some default redirection, but that will disable parent state as a real target (e.g. here Redirect a state to default substate with UI-Router in AngularJS)
Here discuss about AngularJS Routing Using UI-Router, you will get enough idea about nested view and multiple view.
https://scotch.io/tutorials/angular-routing-using-ui-router
I found a simple solution here.
$urlRouterProvider.when('/actionplans', '/actionplans/summary');//<-- Add in this line
$stateProvider
.state('actionplans', {
url: "/actionplans",
abstract: true,/// <-- Add in this line
templateUrl: "pages/actionplans.html",
})
.state('actionplans.planning', {
url: "/planning",
templateUrl: "pages/actionplans.planning.html",
})
.state('actionplans.summary', {
url: "/summary",
templateUrl: "pages/actionplans.summary.html",
})
This will load nest view actionplans.summary.html by default when you call /actionplans. My apology that I did not make this clearer in my question so I post the answer here hopefully it will help someone else with the similar scenario.
I'd like my Angular website to get several routes using ui-router, which are:
/ which renders landing.html
/howto which renders howto.html
I tried the following, with no success:
$stateProvider
.state('landing', {
url: '/',
templateUrl: 'views/landing.html',
controller: 'LandingCtrl',
data : { pageTitle: 'Landing' }
})
.state('howto', {
url: '/howto',
templateUrl: 'views/howto.html',
controller: 'HowToCtrl',
data : { pageTitle: 'HowTo' }
});
I can access landing.html on localhost/ but cannot access /howto, I get the message Cannot GET /howto. Do you have any idea?
I have an Angular app with several nested controllers and views. I implemented infinite scrolling in it closely based on this tutorial for ngInfiniteScrolling: http://binarymuse.github.io/ngInfiniteScroll/demo_async.html
So I have a service that loads items into an array at $scope.content.items. Then there's an ng-repeat element that shows each result.
$scope.content = new Content()
$scope.content.loadMore( $scope.currentStream, 2 ) // this part is actually called in the HTML, but while debugging I've just done it in the controller
Now I want to implement search, and instead of making another search page, just have the items load in place of the current list of items. Basically to take the place of $scope.content.items.
So I built an identical controller, but now calling my search API. I use ng-change to see if someone has typed in the search box, then within the function that calls, do
$scope.search = function() {
$scope.content = new Search()
$scope.content.load( $scope.query )
}
I can see that this works in the console, that it replaces $scope.content.items, by doing this in the browser console:
var scope = angular.element($('[ng-controller=HomeController]')).scope()
scope.content.items
That shows me the array of objects I expect in each case (either before triggering ng-change="search()" or after). But the page itself does not update. It just shows the stuff from the Content() service.
Likewise, if I replace the above two lines from my controller with these below, it shows the content from the Search() service:
$scope.content = new Search()
$scope.content.load( 'thom' )
Long story short, I feel like the services and API work, but the page is not updating when I change the $scope.content.items array used by ng-repeat.
Here is the HTML
<div class="panel panel-item" ng-repeat="item in content.items" ng-hide="hideItem">
<h2 ng-hide=" item.stream == 'read' " data-ng-bind="item.title"></h2>
<a ng-click="openReaderModal( item )" class="cursor-pointer" ng-show=" item.stream == 'read' ">
<h2 data-ng-bind="item.title"></h2>
</a>
// ...
<div class="clearfix"></div>
</div>
Fixed it, somehow. Here is my routes from app.config() before:
$stateProvider
// ...
.state( 'app', {
url: '/app',
templateUrl: 'app/views/app.html',
controller: 'HomeController'
})
.state( 'app.home', {
url: '/main',
templateUrl: 'app/views/home.html',
controller: 'HomeController'
})
.state( 'app.profile', {
url: '/profile',
templateUrl: 'app/views/profile.html',
controller: 'ProfileController'
})
.state( 'app.read', {
url: '/read',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
.state( 'app.watch', {
url: '/watch',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
.state( 'app.listen', {
url: '/listen',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
And here's after:
$stateProvider
// ...
.state( 'app', {
url: '/app',
templateUrl: 'app/views/app.html',
controller: 'HomeController'
})
.state( 'app.home', {
url: '/main',
templateUrl: 'app/views/home.html'
})
.state( 'app.profile', {
url: '/profile',
templateUrl: 'app/views/profile.html',
controller: 'ProfileController'
})
.state( 'app.read', {
url: '/read',
templateUrl: 'app/views/stream-content.html'
})
.state( 'app.watch', {
url: '/watch',
templateUrl: 'app/views/stream-content.html'
})
.state( 'app.listen', {
url: '/listen',
templateUrl: 'app/views/stream-content.html'
})
And it works. If anyone can provide an explanation, I'll credit them the answer.
The routing in angular works like this.
When we provide a controller for the $stateProvider its actually considered as a new constructor (new keyword as in java) thus the data is re-initiated to defaults.
The new constructor will be the child to itself, to access the parent controller one can use the $parent