Save previous state - angular ui-router - angularjs

This is a code of a tutorial about ui router. I have a question about it.
I am trying to find a way to save the previous state for viewB in the code below. What I mean - you can see that route1 state has content only for viewA, viewB isn't there.
My question is - is it possible when I choose route1 state, the viewA to be updated with the template route1.viewA but the right not to be updated to be empty, but the previous content of the right box - route2.viewB or index.viewB to stay there depends on the previous state?
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>AngularJS: UI-Router Quick Start</title>
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" ui-sref="index">Quick Start</a>
<ul class="nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="route1">Route 1</a></li>
<li><a ui-sref="route2">Route 2</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="span6">
<div class="well" ui-view="viewA"></div>
</div>
<div class="span6">
<div class="well" ui-view="viewB"></div>
</div>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider){
$stateProvider
.state('index', {
url: "",
views: {
"viewA": {
template: "index.viewA"
},
"viewB": {
template: "index.viewB"
}
}
})
.state('route1', {
url: "/route1",
views: {
"viewA": {
template: "route1.viewA"
}
}
})
.state('route2', {
url: "/route2",
views: {
"viewA": {
template: "route2.viewA"
},
"viewB": {
template: "route2.viewB"
}
}
})
})
</script>
</body>
</html>

It could work during the transition from index to route1 if route1 is a child state of index. See this plunker.
But in the case you describe, the state route1 must be a parent of both the state index and route2 which is not possible (only one parent for a child).

Related

By using directive to create navbar ,click a item in navbar,the template hetml in ng-view is empity

I create a navbar by using directive of angularjs,now I want click a item in navbar to display a template html file in the ng-view tag,but it does not work.
How should I do? would appreciate any help.
Thanks in advance
index.html
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>Title</title> <linkrel="stylesheet"href="bower_components/bootstrap/dist/css/bootstrap.css"> <linkhref="https://cdn.bootcss.com/fontawesome/4.7.0/css/fontawesome.css"rel="stylesheet">
</head>
<body>
<na></na>
<div ng-view></div>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular/angular-route.js"></script>
<script src="bower_components/angular/angular-animate.js"></script>
<script src="bower_components/angular/angular-sanitize.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
var app=angular.module("app",['ngRoute']);
app.directive('na',function () {
return {
restrict: "EA",
replace: true,
transclude: true,
scope:{
items:'#items',
},
templateUrl:'./tpl/index/tmpl/tplindex.html',
// template: '<ul ng-repeat="item in items" class="nav navbar navbar-default"> <li><i class="{{item.icon}}" aria-hidden="true"></i>{{item.name}}</li> </ul>',
link:function($scope, element, attrs){
$scope.items=[{name:'system',icon:'fa fa-windows fa-2x',id:'system'},
{name:'recognition',icon:'fa fa-indent fa-2x',id:'recognition'},
{name:'route',icon:'fa fa-indent fa-2x',id:'route'},
{name:'auth',icon:'fa fa-user-circle-o fa-2x',id:'auth'},
{name:'strategy',icon:'fa fa-windows fa-2x',id:'strategy'},
{name:'strategy',icon:'fa fa-windows fa-2x',id:'static'}
];
}
}
}).config(['$routeProvider', '$controllerProvider',
function($routeProvider, $controllerProvider) {
$routeProvider.
when('/recongition', {
template:'this is test info'
}).
when('/system', {
templateUrl: './tpl/system/system.html'
}).
when('/route', {
templateUrl: 'tpl/route/route.html'
//controller: 'routeController',
//directive:'routeDrective'
}).
when('/auth', {
templateUrl: 'tpl/auth/auth.html'
}).
when('/strategy', {
templateUrl: 'tpl/strategy/strategy.html'
}).
when('/static', {
templateUrl: './tpl/static/static.html'
}).
otherwise({
redirectTo: '/static' //angular就喜欢斜杠开头
});
}]);
tplindex.html
<nav class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header" style="margin-left: 20px">
<a class="navbar-brand" href="#" style="font-size: xx-large"> Panabit</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav" ng-repeat="item in items">
<li></i> {{item.name}}</li>
</ul>
</div><!--/.nav-collapse -->
</nav>
You need to use the ng-href directive instead of href in order for you to use angular interpolation {{item.id}} in your urls. So your link should look like this instead:
<li><a ng-href="#/{{item.id}}" ><i class="{{item.icon}}"></i> {{item.name}}</a></li>
If that doesn't work, it might try to use html5mode routes, so you could try disabling it, by adding
$locationProvider.html5Mode(true);
where you add your route configuration.
It would be helpful if you added a Plunker (or similar) with your code, so we can play around with it ourselves.
Other notes
You don't need your directive to be transclusive
You don't seem to pass anything to the items-scope variable, so you can remove that and simply use scope: true
You should perhaps use the angular 1.5 components instead (assuming you're using angular 1.5 or above)

angular-ui-router Multiple Views

I'm new to use angular-ui-router, I has a index.html and javascript like this:
var mainApp = angular.module('mainApp',['ui.router']);
mainApp.config(['$stateProvider', '$urlRouterProvider','$httpProvider',
function($stateProvider, $urlRouterProvider,$httpProvider){
$urlRouterProvider.when('','/index');
$stateProvider.state('index',{
url:"/index",
views:{
'menu':{
templateUrl:'views/menu.html'
},
'content':{
templateUrl:'views/content1.html'
}
}
}).state('index.content1',{
url:"index/content1",
views: {
'content#index': {
templateUrl: 'views/content1.html'
}}
}) .state('index.content2',{
url: 'index/content2',
views: {
'content': {
templateUrl: 'views/content2.html'
}
}
})
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body ng-app="mainApp">
<div class="container">
<div class="row">
<div class="col-md-12 column text-center bg-primary">
Title
</div>
</div>
<div class="row">
<div class="col-md-3 column bg-danger">
<div ui-view="menu"></div>
</div>
<div class="col-md-9 column bg-info">
<div ui-view="content">
</div>
</div>
</div>
</div>
</body>
</html>
menu.html
<ul>
<li><a ui-sref="index.content1" ui-sref-active="active">menu1</a></li>
<li><a ui-sref="index.content2" ui-sref-active="active">menu2</a></li>
</ul>
But when I chlick "menu1" or "menu2" link in then menu.html, "content1" or "content2" not be load, Where am i going wrong?
Change child states URL to be mentioning on child route part. Ui-router engine will take care of URL formation based on states hierarchy.
And then make your make your content named view as relative by adding # after your named view, since you wanted to changed named view which is the part of index(parent) state.
.state('index.content1', {
url: "/content1",
views: {
'content#': {
templateUrl: 'views/content1.html'
}
}
}).state('index.content2', {
url: '/content2',
views: {
'content#': {
templateUrl: 'views/content2.html'
}
}
})
Plunker Demo

Custom directive not displaying withing a ui-view

I have a custom dircetive "3-test-directive" which I want to call to display a text. When I use this directive in the page partial-home.html, it does not diaplay me with any text from the directive(it seems the directive did not work).
When I use the same code <3-test-directive/> inside of index.htm, the directive is correctly parsed. Why did not the one with the partial-home.html did not work and how can I fix this ?
Demo for this code : https://plnkr.co/edit/wy5gkUlXmbRpyrdqwHwd?p=preview
index.html
<!-- CSS (load bootstrap) -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style>
.navbar { border-radius:0; }
</style>
<!-- JS (load angular, ui-router, and our custom js file) -->
<script src="https://code.angularjs.org/1.2.13/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="app.js"></script>
</head>
<!-- apply our angular app to our site -->
<body ng-app="routerApp">
<!-- NAVIGATION -->
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="#">AngularUI Router</a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
</ul>
</nav>
<!-- MAIN CONTENT -->
<!-- THIS IS WHERE WE WILL INJECT OUR CONTENT ============================== -->
<div class="container">
<div ui-view></div>
</div>
<div class="text-center">
<p>A tutorial by scotch.io</p>
<p>View the tutorial: AngularJS Routing using UI-Router</p>
</div>
</body>
</html>
app.js
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'
})
// nested list with custom controller
.state('home.list', {
url: '/list',
templateUrl: 'partial-home-list.html',
controller: function($scope) {
$scope.dogs = ['Bernese', 'Husky', 'Goldendoodle'];
}
})
// nested list with just some random string data
.state('home.paragraph', {
url: '/paragraph',
template: 'I could sure use a drink right now.'
})
// ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
.state('about', {
url: '/about',
views: {
'': { templateUrl: 'partial-about.html' },
'columnOne#about': { template: 'Look I am a column!' },
'columnTwo#about': {
templateUrl: 'table-data.html',
controller: 'scotchController'
}
}
});
});
routerApp.controller('scotchController', function($scope) {
$scope.message = 'test';
$scope.scotches = [
{
name: 'Macallan 12',
price: 50
},
{
name: 'Chivas Regal Royal Salute',
price: 10000
},
{
name: 'Glenfiddich 1937',
price: 20000
}
];
});
You can't include scripts in templates...they get stripped out.
Just register the directive in your js file
var routerApp = angular.module('routerApp', ['ui.router'])
.directive("w3TestDirective", function() {
return {
restrict:'E',
template : "<h1>Made by a directive!</h1>"
};
})
DEMO

How to display nav menu while using ui router

I'm trying to display navigation bar menu items using ng-repeat and I'm using ui router simultaneously, but output is not what I expected.
<!--HTML-->
<body>
<div ng-app="navApp" ng-controller="navCtrl">
<a ng-repeat="item in navItems" ui-sref="{{item.sref}}">{{item.label}}</a>
</div>
<div ng-app="mainApp">
<div ui-view></div>
</div>
</body>
//JS
angular.module('navApp', []).controller('navCtrl', function($scope){
$scope.navItems = [
{'sref': 'home', 'label': 'Home'},
{'sref': 'login', 'label': 'Login'},
{'sref': 'signup', 'label': 'Signup'},
{'sref': 'other', 'label': 'Label'}
];
});
var app = angular.module('mainApp', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider){
// $urlRouterProvider.otherwise('/');
$stateProvider.state('login', {
url: '/login',
templateUrl:'login.html',
controller: function($scope) {
$scope.message = 'Login Page'
}
}).state('signup', {
url: '/signup',
templateUrl:'signup.html',
controller: function($scope) {
$scope.status = 'Signup Page'
}
}).state('home', {
url: '/',
template:'Home Page'
}).state('other', {
url: '/other',
template:'Other Page'
});
});
I'm getting output as:
HomeLoginSignupLabel
Here sref are not working as href. Using static navigation menu instead of displaying dynamically then everything is working fine. I think both apps are executing at same causing this issue.
use some navbar like bootsrap or semantic-ui etc.
bootstrap example :
<body>
<div ng-app="navApp" ng-controller="navCtrl">
<nav class="navbar navbar-inverse">
<ul class="nav navbar-nav">
<li ng-repeat="item in navItems"><a ui-sref="{{item.sref}}">{{item.label}}</a></li>
</ul>
</nav>
<div ng-app="mainApp">
<div ui-view></div>
</div>
</body>

ui-router dots in name not working

The UI-Router docs shows that you can use dots in route name:
<!-- partials/state1.html -->
<h1>State 1</h1>
<hr/>
<a ui-sref="state1.list">Show List</a>
<div ui-view></div>
But however in my app this doesn't work. This is an example that worked fine until I changed client to client.ts everywhere:
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>AngularJS: UI-Router Quick Start</title>
<!-- Bootstrap CSS -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" ui-sref="index">Quick Start</a>
<ul class="nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="clien.ts">Clients</a></li>
<li><a ui-sref="route1">Route 1</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="span6">
<div class="well" ui-view=""></div>
</div>
<div class="span6">
<div class="well" ui-view="viewB"></div>
</div>
</div>
<!-- Angular -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<!-- UI-Router -->
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<!-- App Script -->
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider){
$stateProvider
.state('index', {
url: "",
views: {
"": {
template: "index.viewA-index"
},
"viewB": {
template: "index.viewB"
}
}
})
.state('route1', {
url: "/route1",
views: {
"": {
template: "route1.viewA-route1"
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('clien.ts', {
url: "/clients",
views: {
"viewB": {
template: "clients.viewA-route2"
},
"": {
controller: function($scope, ClientService) {
console.log('Controller code being run');
$scope.clients = ClientService.clientList();
},
templateUrl: 'client-list-template.html'
}
}
})
})
.service('ClientService', function() {
this.clientList = function() {
clients = [{'name': 'Acme Food', 'description': 'Makers of fine food'},
{'name': 'Dog Biscuits Inc', 'description': 'Cruncy creations for canines'},
{'name': 'Parrot treats Ltd', 'description': 'Puveyors of bird food'},
{'name': 'Pond supplies', 'description': 'Sell fish and gravel'}];
return(clients);
}
});
</script>
</body>
</html>
Plunker here: http://plnkr.co/edit/ZD7WlC9aKzpwte9dVMxC?p=preview
As you can see the link can't be clicked :/
What you need to do is add an abstract state for clien in that case.
Here's the plunkr, with the added state: plunkr
Whenever you define states with the dot. You still need to at least define the abstract state for the child. In your case for clien.
Also something from the docs
If you register only a single state, like contacts.list, you MUST define a state called contacts at some point, or else no states will be registered. The state contacts.list will get queued until contacts is defined. You will not see any errors if you do this, so be careful that you define the parent in order for the child to get properly registered.

Resources