Problems with nested views using angular-ui-router - angularjs

I have the following code in my app.js:
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/login/login.html'
})
.state('admin', {
url: '/admin',
templateUrl: 'app/admin/layout/layout.html',
abstract: true
})
.state('admin.dashboard', {
url: '',
templateUrl: 'app/admin/dashboard/dashboard.html'
})
.state('admin.client', {
url: '/client',
templateUrl: 'app/admin/client/client.html',
controller: 'ClientController',
})
.state('admin.client.new', {
url: '/client/new',
templateUrl: 'app/admin/client/new.html',
controller: 'ClientController',
})
Then, on layout.html I have this:
<section class="content" ui-view></section>
Which loads the admin.dashboard by default. And from there I have a link to load the admin.client
It's fine. But the problem comes in my client.html. I got the following:
<a ui-sref=".new">
<button class="btn btn-app">
<i class="ion ion-plus"></i> New Client
</button>
</a>
What I expect it to do is to change the ui-view in layout.html from client/client.html to client/new.html but nothing happens.
If I add an ui-view tag inside client.html then the new.html is loaded there. But I need it to load on ui-view of layout.html.

If you use the attribute ui-view without specifying view name like ui-view="myviewname", stateProvider is matching the view hierarchy (the nested ui-view attributes) to your state hierarchy. So its expecting to find the target ui-view in client.html, like you found out yourself.
Change the state name 'admin.client.new' to 'admin.newclient', and your ui-sref link to 'admin.newclient'. Maybe that's what you want.

StrangeLoop's answer worked but I found a better solution.
I added the parent parameter to the new client state. Now it looks like:
.state('admin.client.new', {
parent: 'admin',
url: '/client/new',
templateUrl: 'app/admin/client/new.html',
controller: 'ClientController',
})
And on client.html:
<a ui-sref="admin.client.new">
<button class="btn btn-app">
<i class="ion ion-plus"></i> Novo Cliente
</button>
</a>

Related

Cant access a view within a state in angular-ui-router

I am trying to link to a substate and can't figure out how to get it to work. Here is the link:
<a ui-sref="tab.communityDashboard" class="button button-block button-large"><i class="icon ion-home"></i><br />Community Directory</a>
and here is the route:
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.communityDashboard', {
url: '/communitydashboard',
views: {
'tab-communityDashboard': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
and then eventually:
$urlRouterProvider.otherwise('/home');
Here is the content of the view:
<ion-view view-title="tab-communityDashboard">
<ion-content>
yolo yolo yolo
</ion-content>
</ion-view>
I tried also going to localhost:8100/#/communitydashboard but it just redirects me home. How do I fix this.
You need an <ion-nav-view> where you want your view to show up, and since you're using views with your states, you'll need to include the name attribute with the name of the view, so something like <ion-nav-view name="tab-communityDashboard">
http://ionicframework.com/docs/api/directive/ionNavView/
http://learn.ionicframework.com/formulas/navigation-and-routing-part-1/

How to activate default nested state inside nested states?

I have nested states inside neste state here is controller definition:
(function () {
"use strict";
angular.module("gameManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/game/MultiStepForm/step1");
$urlRouterProvider.otherwise("/game/Home");
$stateProvider
.state("Home", {
url: "/game/Home",
templateUrl: "/app/game/GameView.html",
controller: "GameController",
controllerAs: "vm"
});
$stateProvider
.state("Log", {
url: "/Game/Log",
templateUrl: "/app/Log/GameLogView.html",
controller: "GameLogController",
controllerAs: "vm"
});
$stateProvider
.state("MultiStepForm.view", {
url: "/Game/MultiStepFormView",
templateUrl: "/app/MultiStepForm/MultiStepFormView.html",
controller: "MultiStepFormViewController",
controllerAs: "MultiStepViewLogic"
})
$stateProvider
.state("MultiStepForm.Edit", {
url: "/Game/MultiStepFormEdit",
templateUrl: "/app/MultiStepFormEdit/MultiStepForm.html",
controller: "MultiStepFormEditController",
controllerAs: "MultiStepEditLogic"
})
.state('MultiStepForm.Edit.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep1.html'
})
.state('MultiStepForm.Edit.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep2.html'
})
.state('MultiStepForm.Edit.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep3.html'
});
}]);
})();
This rows define multi-step form:
.state('MultiStepForm.Edit.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep1.html'
})
.state('MultiStepForm.Edit.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep2.html'
})
.state('MultiStepForm.Edit.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/NestedViews/FormStep3.html'
});
Here is view of MultiStepForm.Edit state:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref="MultiStepForm.Edit.step1"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
When MultiStepForm.Edit state activated no netsed view has been displayed they have been display only when the user press button in view form and UI-SREF activate appropriate state.
My question is how can I make MultiStepForm.Edit.step1 state display associated view by default when MultiStepForm.Edit state activated?
The most simple way here would be to use the $urlRouterProvider.when()
$urlRouterProvider.when("/game/MultiStepForm", "/game/MultiStepForm/step1");
Check the doc:
when(what, handler)
Registers a handler for a given url matching. if handle is a string, it is treated as a redirect, and is interpolated according to the syntax of match (i.e. like String.replace() for RegExp, or like a UrlMatcher pattern otherwise).
If the handler is a function, it is injectable. It gets invoked if $location matches. You have the option of inject the match object as $match.
The handler can return
falsy to indicate that the rule didn't match after all, then $urlRouter will continue trying to find another one that matches.
string which is treated as a redirect and passed to $location.url()
void or any truthy value tells $urlRouter that the url was handled.

AngularJS : How do I nest a view within a parent state with parameters?

I'm using the Ionic Framework to create a mobile app, but I'm having a difficult time with the UI Router. I've gotten a few screens working properly, but I can't seem to get nested views working on a state with parameters. I'd like a URL that looks like /legislator/1/profile. It would have a header with the name of legislator #1 and tabs below. The profile tab would be automatically visible and clicking on other tabs (e.g. /legislator/1/votes) would change the content, but not the header
I wound up abandoning the tabs & sidemenu starter projects to customize my nested views. Here's what I have in app.js. The home and people.* states work correctly, but I can't seem to load the legislator screen with the profile view in place. I've tried changing the abstract & controller attributes, but no luck yet.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/home.html",
controller: "homeController"
})
.state('people', {
url: "/people",
abstract: true,
templateUrl: "templates/people.html"
})
.state('people.legislators', {
url: "/legislators",
templateUrl: "templates/legislators.html",
controller: "legislatorController"
})
.state('people.following', {
url: "/following",
templateUrl: "templates/following.html",
controller: "followingController"
})
.state('legislator', {
url: "/legislator/{legislatorId:int}",
templateUrl: "templates/legislator.html",
abstract: true
})
.state('legislator.profile', {
url: "/legislator/{legislatorId:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
.state('legislator.votes', {
url: "/legislator/{legislatorId:int}/votes",
templateUrl: "templates/legislator.votes.html",
controller: "votelistController"
})
$urlRouterProvider.otherwise('/home');
// if none of the above states are matched, use this as the fall-back
})
How is this scenario supposed to work in the UI Router? Once I have $stateProvider configured, how should the tabs link to the nested states?
Thanks for any help you can give me.
Maybe your solution is as simple as replacing the classic href by Ui Router's ui-sref:
replace
<ion-tab ... href="#/legislator/{ scopeLegislatorId }/profile">...</ion-tab>
by
<ion-tab ... ui-sref="legislator.profile({ legislatorId: scopeLegislatorId })">...</ion-tab>
Where scopeLegislatorId is the legislatorId, available from your scope.
If that doesn't help, please provide us with your html files (e.g. legislator.html and legislator.profile.html).
You can use following method to create separate views.
state('people.following',{
data:{
anyVar: {
label: 'cp',
text : 'anyText'
}
},
views: {
'content#people': angularAMD.route({
template: infoView,
controller: 'custInfoCtrl',
controllerUrl: 'modules/custCtrl'
}),
'mobileView#people': angularAMD.route({
template: mobileView,
controller: 'mobileCtrl',
controllerUrl: 'modules/mobileBottomViewCtrl'
})
}
})
<pre>
<div ui-view='contentArea'> </div>
<div ui-view='mobileView'> </div>
</pre>
RobYed pointed me in the right direction to figure out the right way to define my states. Here's the bones of what I wound up with.
app.js:
.state('legislator', {
url: "/legislator",
templateUrl: "templates/legislator.header.html",
abstract: true,
})
.state('legislator.profile', {
url: "/{seq_no:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
templates/legislator.header.html:
<ion-nav-view animation="slide-left-right">
<div class="bar bar-header" ng-controller="profileController">
{{legislator.name}}
</div>
<div class="tabs tabs-striped tabs-top">
<a class="tab-item" ui-sref="legislator.profile" ng-class="{selected: is('legislator.profile')}">
{{'Profile' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.votes" ng-class="{selected: is('legislator.votes')}">
{{'Votes' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.stats" ng-class="{selected: is('legislator.stats')}">
{{'Stats' | translate}}
</a>
</div>
<div ui-view></div>
</ion-nav-view>
templates/legislator.profile.html:
<ion-content>
<div class="bar bar-stable has-subheader" style="height:145px;">
{{legislator.whatever}}
Content Here
</div>
</ion-content>
profileController.js:
'use strict';
angular.module('myApp').controller('profileController', function($scope, $rootScope) {
$scope.legislator = $rootScope.legislators[$stateParams.seq_no-1];
});
Links from other states:
<a ui-sref="legislator.profile({seq_no:legislator.seq_num})"></a>

Use angular ui route to pass query parameters

I'm using Angular ui route and I'm trying to pass query parameters but it doesn't work. I have followed the official wiki.
In the view I have the following code very simple
<div ng-controller="MainController">
<a ng-href="#/foo/bar?param={{make}}"><li>{{make}}</li></a>
</div>
and this is the config
function config($stateProvider, $urlRouterProvider) {
$stateProvider
.state('foo', {
url: '/foo',
templateUrl: '/partials/foo.html',
controller: 'MainController'
})
.state('foo.bar', {
url: '/bar?param',
templateUrl: 'partials/foo.bar.html',
controller: 'SecondaryController'
});
}
but when I click on the link in the view the url I get it is what I get but the route doesn't receive the request.
Use ui-sref directive to generate href link
Markup
<div ng-controller="MainController">
<a ui-sref="foo.bar({param: make})"><li>{{make}}</li></a>
</div>

AngularJs: ui.router does not loading controller

I'l try to use AngularJs with ui.router, but have the trouble.
This example have three states: index, template and template.show
$stateProvider
.state('/', {
url: '',
template: '<a ui-sref="template">GoTo Template Index</a>'
})
.state('template', {
url: 'template',
templateUrl: 'template_index.html',
controller: 'TemplateCtrl'
})
.state('template.show', {
url: '/{templateId:[0-9]+}',
templateUrl: 'template_show.html',
controller: 'TemplateShowCtrl'
})
Please, see plunker: http://plnkr.co/edit/prluQs9vXeJw9IVi2JYW?p=info
But only two first states working. State "template.show" changing, loading template, but does not execute TemplateShowCtrl and not update ui-view to new template.
You can see screenshot
Any child state requires the presence of a subsequent ui-view directive in its parent so that it knows where to insert the html. Currently, there is not one present in the template_index.html markup.
It should instead look something akin to this:
<ul>
<li ng-repeat="t in templates">
<a ui-sref="template.show({templateId:t.id})" href='#'>
{{t.name}}
</a>
</li>
</ul>
<!-- target element -->
<ui-view></ui-view>

Resources