How to implement two panel layout using Angular Ui-Router? - angularjs

This is my code
app.config(['$stateProvider', function($stateProvider){
$stateProvider
.state('student',{
url: '/student',
views: {
'list': {
templateUrl: 'list.html',
controller: 'StudentsCtrl'
},
'edit':{
templateUrl: 'edit.html',
controller: 'StudentEditCtrl'
}
}
})
}]);
<html ng-app="app">
<div ui-view="list"></div>
<div ui-view="edit"></div>
</html>
I have layout with two panels side by side,i tried the above code but at the time of page loading two panels html pages displayed at a time. But i want to display first list.html in left side then user clicks add or edit buttons in list.html that time render the edit.html in right side of the panel.

Any reason why you can't combine the HTML and controller together? The StudentCtrl could toggle showing the edit html when the add or edit buttons are clicked.
I can't think of a simple way to make it work with how you have it designed now. You'd have to some coordinating controller in your main HTML and/or some sort of shared Angular service which seems messy.

Related

angular: updating a view without page reload

I have a rootScope json array that's viewed is several controllers, and gets updated in yet another controller. The json array contains urls that get updated. The view controllers show updated urls about half the time, but if I reload the page, I do get updated views 100% of the time.
I have tried using $scope.$apply() and $timeout, but they made no difference.
Could someone please tell me what angular tools are out there for this? I'm hoping there is a simple approach to it.
Going off of my earlier comment:
Index
<!doctype html>
<html ng-app="myapp">
<head>
<!--Head stuff-->
</head>
<body>
<div ng-view=""></div>
<!-- Scripts, other stuff -->
</body>
</html>
Main Script
'use strict';
angular
.module('myapp', [
//...
'ngRoute',
//...
])
.config(function (..., $routeProvider, ...) {
$routeProvider
.when('/404', {
templateurl: '404.html',
controller: 'ErrorCtrl',
controllerAs: 'errorCtrl',
title: 'You are lost'
})
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeCtrl',
controllerAs: 'homeCtrl',
title: 'Home'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl',
controllerAs: 'contactCtrl',
title: 'Contact Us'
})
.otherwise({
redirectTo: '/404'
});
//...
})
.run (function (...) {
//...
});
Usage
Contact Us
You'd be taking all of the base template code that's common to your pages and be including that on index. Basically, the stuff that doesn't change will always be there. Otherwise, take it off of the main page and put it into a template file with its own controller. Alternatively, have some shared controllers and just use the views as templates, then shovel all of the functionality into directives. I actually prefer the latter method, but the former is shown above.
What's noteworthy about this solution is that the page is only actually loaded once. Since you stay on the index whenever you navigate to a different view, you only need to grab the HTML for the new template from your server and inject it into the view (which ngRoute takes care of). I believe that by default you'll have a # in your URL, so you'll probably want to enable HTML5 mode.$locationProvider into your config function and then add this line:
$locationProvider.html5Mode ({ enabled: true });
You also need to add a base to the head element of your index file:
<base href="/" />
Homework: Routes tutorial, HTML5 mode
If you use Grunt, you might also want to look into ngTemplates. It can really boost performance.

How to target specific ui-view elements when nested ui-views exist

Imagine some html as follows:
<body ng-app="blocksApp">
Some content goes here
<div ui-view="monty">
<div ui-view="dave">Aaa</div>
<div ui-view="pete">Bbb</div>
<div ui-view="steve">Ccc</div>
</div>
</body>
Using ui-router, is there any way to code a state that will set "dave" to a new snippet of html, whilst leaving everything else untouched.
e.g. I'd like to do this:
$stateProvider
.state('daveonly',{
url: "/dave",
views:{
'dave':{template:"Dave now has content"}
}
})
I can't get it to work. The reason I want to do this is that sometimes I'd like to replace 'Dave' with a partial update, other times I'd like to replace the entire 'monty' with a partial update. It seems that ui-router does not like having nested ui-views in the same snippet of html.
From one point of view I'd like to suggest:
move html code to '.tpl.html' files
use 'templateUrl' instead of 'template'
And check if the following is suitable for you:
$stateProvider.state("daveonly", {
views: {
"dave": {
templateUrl: 'daveonly.tpl.html',
},
"pete": {
templateUrl: 'pete.tpl.html',
},
"steve": {
templateUrl: 'steve.tpl.html',
},
}
});
Take a look at page1 and page2 for more details.
But from another point of view it could be more useful to use only one ui-view and to redesign current ui-views to become the appropriate directives with controllers/services: usage of directives with controllers/services could help to manage partial reload correctly and to write unit-tests.
Yes it can be done easily with the help of abstract states and yes you are correct ui-router doesn't like direct nested views directly but it works fine if the views are in any child template.
Now consider this main page(index.html)
<body ng-app="app">
<div ng-view=""></div>
</body>
Now this template which will appear in this unnamed view. (parent.html)
<h3>This is the parent template</h3>
<div ng-view="child1"></div>
<div ng-view="child2"></div>
Now the JS file
$stateProvide.state('home',{
url:'/',
abstract:true,
views:{
"":{
templateUrl:'parent.html'
}
}
})
.state('home.child',{
url:"",
views:{
'child1#home':{
templateUrl:'child1.html'
},
'child2#home':{
template:'Child2'
}
}
})
.state('home.child.child1',{
url:"child1#home.child",
views:{
'child1#home':{
templateUrl:'child1viewchange.html'
}
}
});
(Now the manipulation part)
(child1.html)
<button ui-sref="home.child.child1">Child</button>
Now child1viewchange.html pe jana padega and wo dekhne wali hai kaunsi kaisi thi/......
(child1viewchange.html)
<h3>Child1's view change</h3>
So now when we click on the button in child view1 the content in the first view changes and if we assign controllers then they can use them to control data.

angular material animations and ui-router

I'm using angular-material and ui-router within an angular-meteor project. I managed to successfully use ui-router with angular-material and everything's working except for one thing: if you notice, angular material tabs have a tiny animation making each tab's content slide from left or right when clicking on the tab. Using ui-router this animation is lost. Is there any way to keep it using ui-router? Thanks beforehand.
First of all you need to use 'ui-sref' attribute with states in your tabs instead of this pastebin.com/x4MJLfBE 'ui-view' to display your templates from the states.
<md-tabs md-selected="selectedIndex" md-border-bottom md-autoselect>
<md-tab label="Configuration" ui-sref="admin.configurations"></md-tab>
<md-tab label="Users" ui-sref="admin.users.list"></md-tab>
<md-tab label="Songs" ui-sref="admin.songs"></md-tab>
</md-tabs>
<div ui-view></div>
ui-sref it's your states
.state('admin.configurations', {
url: '/configurations',
templateUrl: 'app/admin/configurations/configurations.tmpl.html',
controller: 'ConfigurationsController as ctrl',
})
.state('admin.users.list', {
url: '/list',
templateUrl: 'app/admin/users/users.tmpl.html',
controller: 'UsersListController as ctrl'
})
Plus your parent state must be abstract. It means that now you in admin state where you have template with your tabs
.state('admin', {
url: '/admin',
templateUrl: 'app/admin/admin.tmpl.html',
controller: 'AdminController as ctrl'
})
Ok I solved this way: it is sufficient avoiding "template" or "templateUrl" inside the router state definition and embed each content inside md-tab itself. Let the router state definition just change the url and everything will work.

how to setup ui-router nested views

I am trying to setup my app with ui-router. I am familiar with basic nested views but I am wanting to do something more complex. I have my basic setup for the main views. I would like to have a chat popup that has its own views that are independent from the main views. I want to be able to navigate the main views and not affect the states in the chat popup. So how is this done? Do i need to have a abstract state for the chat? and then have nested views from there?
here is a visual.
and here is a plunker
plunker
$stateProvider
.state('root', {
abstract: true,
views: {
'#': {
template: '<ui-view />',
controller: 'RootCtrl',
controllerAs: 'rootCtrl'
},
'header#': {
templateUrl: 'header.html',
controller: 'HeaderCtrl',
controllerAs: 'headerCtrl'
},
'footer#': {
templateUrl: 'footer.html',
controller: 'FooterCtrl',
controllerAs: 'footerCtrl'
}
}
})
.state('root.home',{
parent:'root',
url:'/home',
templateUrl:'home.html',
controller: 'HomeController',
controllerAs:'homeCtrl'
})
.state('root.about',{
parent:'root',
url:'/about',
templateUrl:'about.html'
});
});
I suggest that, don't use footer as a ui-view, because it is completely independent of your states.
Then how?
Make your footer part as a template and use ng-include to render your footer part.
<footer ng-include="'/footer.html'"></footer>
And within footer.html you can specifies the controller for the footer view.
Benefits
No need to handle footer on each state
No need to pass chat history on every change in state.
Create Chat service/function with controllers in different js files and inject to the index.html and script.js. use bootstrap collapsible modal for pop-up chats.
Looking # your plunkr, you're on right track,though injecting controller from script.js via controllerAs is not scalable for larger app.
Instead you can create js files for each controller and service and separate partial views, just need to inject the services and controllers to index.html and mention partial views in stateprovider function.
I am not sure if You want to use route for the chat but there are two ways for you may be more
Use modals that can collabse and open when clicked like that of facebook here
Modals for bootstrap
Use angulars ngHide ngShow
For your navigation while using at sub elements on chat you can create one state for the chat and nest chat navigation in to you chat state so that any state change will not change your other chat states.
That means you will need to use substate concepts of ui-router

ionic/angularjs app construction

When making an ionic app what is the best method of creating different pages of information?
Right now I have separate html documents for each page and a button pointing to each html document; however, I feel like angular/ionic provides a better way of doing so that I missed. For example, the app I am making has a main page with buttons for 5 places. Each button loads a completely new html document with info about the place labeled on the button.
If it is too much to explain, a link answering what I am asking is fine
Thanks
What you want are angular templates. You can write a template once, and then pass in information from the controller to take the place of the angular bindings. You have one master template, that changes the angular bindings depending on which information you pass it in the controller.
For example, you could have your application load in partial templates for each location, and display them all on your main page without having to hit a new html document. Check out the example in the Angular Tutorial.
And the Live Demo
You can do it by uiROUTER, For example: angular.module('ionicApp', ['ionic']) .config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('menu', { abstract: 'true', templateUrl: 'templates/menu.html', controller: 'MenuCtrl' }) / ... / .state('menu.work', { url: '/work', views: { menuContent: { templateUrl: 'templates/work.html', controller: 'WorkCtrl' } } }); $urlRouterProvider.otherwise('/work'); });

Resources