Using same State for multiple Menu Items in AngularJS - angularjs

I am trying to use the Same State for managing all the Menu Items and the state is not being refreshed properly.
My main page has the following four sections.
<div ui-view="navbar" ng-cloak="" class="codrops-top"></div>
<div ui-view="leftnavbar"></div>
<div class="well" ui-view="content">
</div>
<div class="footer">
</div>
And i have configured Angular Module to handle the top navbar and the left nav bar using
$stateProvider.state('site', {
'abstract': true,
views: {
'navbar#': {
templateUrl: 'scripts/components/navbar/navbar.html',
controller: 'NavbarController'
}
,
'leftnavbar#' :{
templateUrl:'scripts/components/leftnavbar/leftnavbar.html',
controller: 'LeftNavbarController'
}
}
And i am trying to refresh the view "content" when a left nav item is clicked.
My Leftnav Controller has the following handler for nav item click.
$scope.manageEntity = function(code) {
// I am passing the code of the item clicked using a Service.
ElementModel.code = code;
$scope.toggle();
$state.go('instance',{reload: true});
};
And here is the code i am using for defining the state 'instance'
.config(function ($stateProvider) {
$stateProvider
.state('instance',{
parent: 'site',
url: '/instance',
views: {
'content#': {
templateUrl: 'scripts/app/entities/instance/instances.html',
controller: 'InstanceController'
}
}
How ever the first time the InstanceController is getting invoked and from then even though i am clicking on other left nav items the view is not getting refreshed. control is reaching $state.go('instance',{reload:true}); how ever it's not entering the InstanceController.
Not sure what i am doing wrong..
Appreciate your help.
Thanks.

In your handler function $scope.manageEntity" the call to $state.go should probably be like
$state.go('instance',{},{reload: true});

Related

Navigate from one tab to a nested view of another tab

Is it possible to link from one tab to a nested view in another tab? I've tried two different methods and neither seem to work.
Here's my router config:
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.chats', {
url: '/chats',
views: {
'tab-chats': {
templateUrl: 'templates/tab-chats.html',
controller: 'ChatsCtrl'
}
}
})
.state('tab.chat-detail', {
url: '/chats/:chatId',
views: {
'tab-chats': {
templateUrl: 'templates/chat-detail.html',
controller: 'ChatDetailCtrl'
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/dash');
});
In templates/tab-dash.html I have a link to a particular chat detail page:
<ion-view view-title="Dashboard">
<ion-content class="padding">
<h1>My Chats</h1>
Chat #1
</ion-content>
</ion-view>
From here I can navigate the chat detail page, however if I click the "Chats" tab button at the bottom nothing at all happens. I'd like it to bring me to the main Chats page.
Another method I tried was using ui-sref instead of href:
<ion-view view-title="Dashboard">
<ion-content class="padding">
<h1>My Chats</h1>
<a ui-sref="tab.chat-detail{chatId:1}">Chat #1</a>
</ion-content>
</ion-view>
In this case I receive an error Could not resolve 'tab.chat-detail{chatId:1}' from state 'tab.dash'
What's the best way to link to a "detail" view from within another tab? My main is to make sure that clicking the tab button at the bottom always brings me to the parent page for that tab. Right now, in the first example, it gets stuck on the "detail" view.
I got a workaround. I am hiding the tab bar when navigating to nested view of another tab.
And showing it again when user navigates back to the root tab.
To know how to hide and show tab bar programmatically, check this link:-
https://stackoverflow.com/a/45002644/4527624

AngularJS UI Router Update Sibling View

I am working with angular and using ui router. The structure of my views are something like this:
<div ui-view>
<div ui-view="left">
-- list of items
</div>
<div ui-view="right">
-- details of item
</div>
</div>
Now if i select an item from left panel, an api is called to get the details of that item. Now want to load that information in right view.
All the view states have their own controller. Can someone please help me to pass the returned data from api tosecond view?
This is a pretty straightforward and common use case with ui-router. The main concept is of nested states and multiple named-views.
I would set this up with some states that look something like:
$stateProvider
.state('user', {
url: '/user',
views: {
'left': {
templateUrl: '/templates/states/user-list.tpl.html'
},
'right': {
template: '<p>This is default content that would appear in the right view until a user is selected. This is nice, but is completely optional.</p>'
}
}
})
.state('user.details', {
url: '/:userId',
views: {
'right': {
templateUrl: '/templates/states/user-details.tpl.html'
}
}
});
In the user-list template, you would use links something like:
<a ui-sref="user.details({userId: user.id})">{{user.name}}</a>
Because user.details is a child state of user, the user-list stays loaded into the left view while navigating through different users in the right view.

Angular ui-router subview issues

I've been working with Angular for a year or 2 now, but this is my first project using ui-router. I'm running into a few issues with views and sub-views. The app is a standard left-side menu bar, with the views on the right changing depending on what's clicked in the menu bar.
On index.html
<body>
<div ui-view></div>
</body>
In the config.js file, which defines the routes
.state("dashboard", {
url: "/dashboard",
templateUrl: "components/dashboard/dashboard.html",
data: {
pageTitle: "Dashboard",
requiresLogin: false
}
})
.state("dashboard.welcome", {
url: "/welcome",
templateUrl: "components/welcome/welcome.html",
data: {
pageTitle: "Welcome",
requiresLogin: false
}
})
In the dashboard.html file
<div class="dashboard">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-8">
<div ui-view>
The /dashboard path loads correctly, and will load the left-side navigation bar with a blank right side. But changing the state to dashboard.welcome (/welcome) will not load the welcome.html template.
Whenever working with ui-router you need to understand that the concept of states is different from routes. When you define a sub-state, its defined relative to its parent state. In your scenario dashboard.welcome is defined as a child state of dashboard. The routes to substate is relative to the parent and is {parent url}/{child url}. Hence you should use either of the below 2 to route to that state:
Using $state.go change the state by specifying state name
$state.go('dashboard.welcome');
Using $location.path change the route by specifying url
$location.path('/dashboard/welcome');
It sounds like you want links to /welcome to be for state dashboard.welcome. Here is a plunker showing how this can be done. I show two sets of dashboard and welcome states. The first set of states (dashboard & welcome) shows that /dashboard/welcome will bring you to the dashboard.welcome state.
The second set (dashboard2 & welcome2) shows that /welcome will go to state dashboard2.welcome2. I believe this is what you were looking for.
If you hover over the links you can see where they will take you.
https://plnkr.co/edit/AVKPFa?p=info
Nested routes in ui-router get nested urls. I would however recommend using named-views for this kind of structure. You can find more info about it here:
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
The gist of it is: you can specify a named component (ui-view) for your left menu navigation and another one for content, which gives you much more control down the line, because named components can be overwritten in child states or they can keep the default template, depending on your needs.
Example:
.state('root', {
url: '',
abstract: true,
views: {
'header': {
templateUrl: 'templates/partials/header.html',
controller: 'headerCtrl'
},
'logo': {
templateUrl: 'templates/partials/logoView.html'
},
'footer':{
templateUrl: 'templates/partials/footer.html',
controller: 'footerCtrl'
}
}
})
.state('root.login', {
url: '/login',
views: {
'header#': {
template: ''
},
'container#': {
templateUrl: 'templates/login.html',
controller: 'loginController'
}
}
})
.state('root.report', {
url: '/report',
views: {
'container#': {
templateUrl: 'templates/eu_dashboard.html',
controller: 'reportController'
}
}
})
And in your index.html:
<div ui-view="logo"></div>
<div ui-view="header"></div>
<div id="mainView" ui-view="container"></div>
<div ui-view="footer"></div>

Angular ui-router ui-sref redirects back to calling page, even though destination page renders correctly

I'm a newb and have to be doing something stupid here, and I can't figure it out for the life of me. Thanks in advance for any help!
In short, I have 3 pages that all load correctly when visiting them directly through the address bar in a browser:
#/communities
#/companies
#/companies/:id
I have used ui-router to define the company states as follows:
//companies.js file:
.config(function config( $stateProvider ) {
$stateProvider
.state( 'companies', {
url: '/companies',
views: {
"main": {
templateUrl: 'companies/companies.tpl.html'
}
},
data:{ pageTitle: '' }
});
})
//companies.detail.js file:
.config(function config( $stateProvider ) {
$stateProvider
.state( 'companies.detail', {
url: '/:id',
views: {
//use # to force use of parent ui-view tag
"main#": {
templateUrl: 'companies/companies.detail/companies.detail.tpl.html'
}
},
data:{ pageTitle: '' }
});
})
.controller('CompanyDetailCtrl', ['CompaniesService', '$stateParams',
function(CompaniesService, $stateParams) {
alert($stateParams.id); //this fires when I navigate to page briefly
var _this = this; //need to get better approach for this (ideally remove)
_this.hoas = [];
CompaniesService.getCompanyHoas($stateParams.id).then(function(response) {
_this.hoas = response;
});
}])
;
//communities.tpl.html calling page snippet:
<a ui-sref="companies.detail({id:hoa.company.id})">{{hoa.company.name}}</a>
The URL is created correctly when I hover over in a browser (ie: "companies/223") AND the companies/223 page is correctly navigated to BUT only for a split second and then redirects back to the calling page. The page IS caught in browser history (so I can go back to it and stay on it and it works perfectly), but when I click this link it always redirects back.
What am I missing??? It's killing me. Thanks for your help. :)
The reason the state was always redirecting back to the calling page is because I had teh ui-sref wrapped in a parent ui-sref element that was pointing back to the calling page:
<a ui-sref="companies" class="list-group-item"
ng-click="list.selectCommunity(community)"
ng-switch on="list.isSelected(community)"
ng-class="{'active': list.isSelected(community)}" >
<div ng-switch-when="true">
<div class="table-responsive">
<table class="table">
...
<td class="hidden-xs"><a ui-sref="companies.detail({id:hoa.company.id})">{{hoa.company.name}}</a></td>
...
</table>
</div>
</div>
</a>
I easily corrected this by changing the first line to:
<a href="#" class="list-group-item" ...
Hope this helps someone in the future. I just wish I didn't assume the problem was within my JS!

AngularJS navigation bar directive with a refresh button

I looked online for a solution but I couldn't find one that suites my needs. Tried this and looked into this with no help.
My case is, I designed a mobile app with AngularJS and the app has a navigation bar. Every page has this navigation bar because of that, I decided to move the code to a directive. The navigation bar has a button inside of it and this button will be used to force a refresh on the app's data (similar to facebook's pull to refresh). The navigation bar is displayed in all pages and whenever the user are, if he click's on the button the app has to execute an update and redirects to a certain page to display the results.
The problem is, since the navigation is inside of a directive and the user can click on any screen how do I manage capturing the click on the button, calling the refresh function and redirecting to a page?
Here is my directive and one of the pages I used it.
myAppDirectives.directive('headerMenu', function() {
return {
restrict: 'A',
templateUrl: 'partials/templates/header-menu.html'
};
});
<div class="topcoat-navigation-bar">
<div class="topcoat-navigation-bar__item left quarter">
<a class="topcoat-icon-button--quiet" snap-toggle>
<span class="topcoat-icon icon-menu-stack"></span>
</a>
</div>
<div class="topcoat-navigation-bar__item right three-quarters">
<a class="topcoat-icon-button--quiet" href="" > <!-- THIS IS THE REFRESH BUTTON -->
<span class="topcoat-icon icon-refresh"></span>
</a>
</div>
Page example:
<div header-menu></div>
<div> MAIN CONTENT </div>
Thank you!
Update 2: I do appreciate the answers about using ui-router. Since my project is already running and almost ready, structural changes like that are not in question. The accepted answer was the one that solved my problem although the others might fit better other people.
Just put a ngClick on this button:
<a class="topcoat-icon-button--quiet" ng-click="redirect()">
And provide a redirect function on the directive's scope:
myAppDirectives.directive('headerMenu', function() {
return {
scope:{},
restrict: 'A',
templateUrl: 'partials/templates/header-menu.html',
link: function(scope){
scope.redirect = function(){
// redirect to...
}
}
};
});
When I need to do this, I use ui-router, and create a view hierarchy that keeps the navigation bar loaded for every page. That way I can have for example, a navbar.html partial, and a state setup like the following:
$stateProvider
.state('header', url: '', templateUrl: 'header.html', controller: 'HeaderCtrl' })
.state('header.page', url: '/somepage', templateUrl: 'page.html', controller: 'PageCtr' })
.state( ...
I agree with Matt Way, ui-router is great solution for syncing nav bars. Although, for my projects I've been using Multiple Named Views config with ui-router, and your able to get real-time sync between main app interactions and the nav bar, negating the need for "refresh buttons".
In addition, if the user wants to return to the previous page, ui-router will maintain app "state", forms/UX/etc will still be as before.
Have a look at the ui-router wiki https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views.
Basic demo with header sync http://plnkr.co/edit/kYPGZw?p=preview
Basic multi view config (viewC is Nav):
$stateProvider
.state('state1', {
url: "/",
views: {
"viewA": {
template: "1st Tab, index.viewA"
},
"viewB": {
template: '1st Tab, index.viewB<br><a ui-sref=".list">Show List</a>' +
'<div ui-view="viewB.list"></div>'
},
"viewC": {
template: '1st Tab, index.viewC <div ui-view="viewC.list"></div>'
}
}
})
.state('state1.list', {
url: 'list',
views: {
"viewB.list": {
template: '<h2>Nest list viewB</h2><ul>' +
'<li ng-repeat="thing in tab1things">{{thing}}</li></ul>',
controller: 'Tab1ViewBCtrl',
data: {}
},
"viewC.list": {
template: '1st Tab, list.viewC'
}
}
})

Resources