how to implement controller with ui-router angularJS - angularjs

im trying to use ui-router in AngularJS for the first time, but i think ive set up script.js file incorrectly. Any help would be appreciated. Is the problem with the app.controller?? Where have i gone wrong?
var app = angular.module("catalogue", ['ui.router'])
app.config(function($stateProvider) {
var homeState = {
name: 'home',
url: '/home',
templateUrl: 'home.html',
controller: 'HomeCtrl'
},
var category1State = {
name: 'category1',
url: '/category1',
templateUrl: 'category1.html',
controller: 'Category1Ctrl'
},
var category2State = {
name: 'category2',
url: '/category2',
templateUrl: 'category2.html',
controller: 'Category2Ctrl'
},
var category3State = {
name: 'category3',
url: '/category3',
templateUrl: 'category3.html',
controller: 'Category3Ctrl'
};
otherwise({redirectTo: '/home' })
$stateProvider.state(homeState);
$stateProvider.state(category1State);
$stateProvider.state(category2State);
$stateProvider.state(category3State);
});
app.controller('HomeCtrl', ['$scope', '$http', function($scope, $http, $stateParams) {
$http.get('home.json').then(function(response){
$scope.home = response.data;
});
}])
app.controller('Category1Ctrl', ['$scope', '$http', function($scope, $http, $stateParams) {
$http.get('category1.json').then(function(response){
$scope.category1 = response.data;
});
}])
app.controller('Category2Ctrl', ['$scope', '$http', function($scope, $http, $stateParams) {
$http.get('category2.json').then(function(response){
$scope.category2 = response.data;
});
}])
app.controller('Category3Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('category3.json').then(function(response){
$scope.category3 = response.data;
});
}])
and my index.html
<!DOCTYPE html>
<html lang="en" ng-app="catalogue">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title> Catalogue </title>
<!-- Bootstrap core CSS -->
<link href="bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- The justified navigation menu is meant for single line per list item.
Multiple lines will require custom code not provided by Bootstrap. -->
<div class="masthead">
<h3 class="text-muted"> Catalogue </h3>
<nav>
<ul class="nav nav-justified">
<li><a ui-sref="home" ui-sref-active="active">Home </a></li>
<li><a ui-sref="category1" ui-sref-active="active">Category1</a></li>
<li><a ui-sref="category2" ui-sref-active="active">Category2</a></li>
<li><a ui-sref="category3" ui-sref-active="active">Category3</a></li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</nav>
</div>
<div ng-controller="HomeCtrl">
<div ng-view></div>
</div>
<!-- Site footer -->
<footer class="footer">
<p>© 2017 Company, Inc.</p>
</footer>
</div> <!-- /container -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="script.js"></script>
<ui-view></ui-view>
</body>
</html>

Heres an example codepen to get you started, hope it helps:
(function() {
'use strict';
function config($stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
controller: 'MainController as vm'
})
.state('other', {
url: '/other',
controller: 'OtherController as vm'
});
$httpProvider.interceptors.push(function() {
return {
response: function(res) {
/* This is the code that transforms the response. `res.data` is the
* response body */
res.data = {
data: data
};
res.data.meta = {
status: res.status
};
console.log(JSON.stringify(res));
return res;
}
};
});
}
function cacheFactory($cacheFactory) {
return $cacheFactory('headlineCache', {
capacity: 1
});
}
function MainController(httpInterceptor) {
var vm = this;
console.log('MainController');
vm.title = 'Main Title';
httpInterceptor
.consoleLog();
}
function OtherController() {
var vm = this;
vm.title = 'Other Title';
console.log('OtherController');
}
function httpInterceptor($http) {
return {
consoleLog: consoleLog
};
function consoleLog() {
return console.log('httpInterceptor');
}
}
function contactCard() {
return {
scope: false,
restrict: 'E',
template: '<div><h2></h2><p></p></div>'
};
}
angular
.module('app', ['ui.router'])
.config(config)
.controller('MainController', MainController)
.controller('OtherController', OtherController)
.directive('contactCard', contactCard)
.factory('cacheFactory', cacheFactory)
.factory('httpInterceptor', httpInterceptor);
}());
.container-fluid {
background-color: #222;
color: #fff;
aside {
position: absolute;
left: 1px;
top: 5px;
ul {
list-style-type: none;
padding: 10px;
li {
margin: 0 0 4px 4px;
}
li a {
padding: 4px;
text-decoration: none;
color: #fff;
}
.active {
background-color: #fff;
color: #222;
border-radius: 4px;
}
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
<div class="container-fluid" ng-app="app">
<aside>
<ul>
<li><a ui-sref="home" ui-sref-active="active">Home</a>
</li>
<li><a ui-sref="other" ui-sref-active="active">Other</a>
</li>
</ul>
</aside>
<div class="container" ui-view>
<h1 class="text-center" ng-bind="vm.title"></h1>
</div>
</div>

Related

Angular route is not showing the view

I want to use routeProvider in ngRoute in angularjs to view my home.html or delete.html or add.html
app.js
var app = angular.module('MyApp', ['ngRoute']);
MyApp.config([
'$routeProvider',
function($routeProvider) {
$routeProvider
.when('/Add', {
templateUrl: 'html/add.html',
controller: 'AddController'
})
.when('/Edit', {
templateUrl: 'html/edit.html',
controller: 'EditController'
})
.when('/Delete', {
templateUrl: 'html/delete.html',
controller: 'DeleteController'
})
.when('/Home', {
templateUrl: 'html/home.html',
controller: 'HomeController'
})
.otherwise({
redirectTo: '/Home'
});
}
]);
MyApp.controller('AddController', function($scope) {
$scope.message = "In add view"
});
MyApp.controller('DeleteController', function ($scope) {
$scope.message = "In delete view"
});
MyApp.controller('EditController', function ($scope) {
$scope.message = "In edit view"
});
MyApp.controller('HomeController', function ($scope) {
$scope.message = "In home view"
});
index.html
<!DOCTYPE html>
<html ng-app="MyApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!-- bootstrap css -->
<link href="Content/bootstrap.min.css" rel="stylesheet"/>
<!-- Jquery js -->
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="Scripts/internal/app.js"></script>
</head>
<body>
<div class="container">
<nav role="navigation" class="navbar navbar-inverse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="">Add</li>
<li class="">Edit</li>
<li class="">Delete</li>
</ul>
</nav>
<div ng-view>
</div>
<!-- Footer -->
<h3 style="margin-top: 40px;" class="text-center text-info">Single Page App</h3>
</div>
</body>
</html>
When I run my application, and click on any of the links, it gives me this url: http://localhost:51285/html/#!Edit
And in the body is this...
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
In the sample that I am following, it doesn't have that error it just changes to the message.
you have some mistake in your code :
in your html:using Add
2.in your app.js:instead of MyApp.config or MyApp.controller use app.config and app.controller.MyApp is name of your app but you must use variable that your app stored on it.
follwing will working:
your html:
<!DOCTYPE html>
<html ng-app="MyApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!-- bootstrap css -->
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<!-- Jquery js -->
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="internal/app.js"></script>
</head>
<body>
<div class="container">
<nav role="navigation" class="navbar navbar-inverse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="">Add</li>
<li class="">Edit</li>
<li class="">Delete</li>
</ul>
</nav>
<div ng-view></div>
<!-- Footer -->
<h3 style="margin-top: 40px;" class="text-center text-info">Single Page App</h3>
</div>
</body>
</html>
your app:
var app = angular.module('MyApp', ['ngRoute']);
app.config([
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/Add', {
templateUrl: 'html/add.html',
controller: 'AddController'
})
.when('/Edit', {
templateUrl: 'html/edit.html',
controller: 'EditController'
})
.when('/Delete', {
templateUrl: 'html/delete.html',
controller: 'DeleteController'
})
.when('/Home', {
templateUrl: 'html/home.html',
controller: 'HomeController'
})
.otherwise({
redirectTo: '/Home'
});
}
]);
app.controller('AddController', function ($scope) {
$scope.message = "In add view";
});
app.controller('DeleteController', function ($scope) {
$scope.message = "In delete view";
});
app.controller('EditController', function ($scope) {
$scope.message = "In edit view";
});
app.controller('HomeController', function ($scope) {
$scope.message = "In home view";
});
I hope it could be ralted with configuration. Please check the link below! Angular force an undesired exclamation mark in url

Angular-material infinite scroll and $http

I've already tried to follow instructions in this question, but I'm stuck, so I had to ask this as a new question.
I am trying to create infinite scroll where a user can see his activities. Only 10 (10 is a hypothetical number here) activities will be shown at a time, so performance will be better.
I created a simple pagination on backend and it works as expected.
/feed/1 -> displays first 10 results (0-10)
/feed/2 -> displays 10 more (10-20)
/feed/3 -> displays 10 more (20-30)
Since I use $http, I couldn't find a way to mimick it, so I put it here as it is for now. There may be more than one issue here, I tried to be careful, though.
Here's my plunk : http://plnkr.co/edit/DLAMy56jwyeqYdN1kvT3?p=preview
Here's my code.
index.html
<!doctype html>
<html lang="en" ng-app="feed">
<head>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<meta charset="UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ui-view></div>
<!-- Everything is in template.html -->
</body>
</html>
template.html
<div class="virtualRepeatdemoInfiniteScroll">
<md-content layout="column">
<md-virtual-repeat-container id="vertical-container" flex>
<div md-virtual-repeat="FeedFlow in PostController.data" md-on-demand class="repeated-item" flex>
<div ng-repeat="text in FeedFlow.feed">
{{FeedFlow.id}} <!-- whose post is this? -->
{{text.status}} <!-- status -->
</div>
</div>
</md-virtual-repeat-container>
</md-content>
</div>
style.css
.virtualRepeatdemoInfiniteScroll #vertical-container {
height: 292px;
width: 400px;
}
.virtualRepeatdemoInfiniteScroll .repeated-item {
border-bottom: 1px solid #ddd;
box-sizing: border-box;
height: 40px;
padding-top: 10px;
}
.virtualRepeatdemoInfiniteScroll md-content {
margin: 16px;
}
.virtualRepeatdemoInfiniteScroll md-virtual-repeat-container {
border: solid 1px grey;
}
.virtualRepeatdemoInfiniteScroll .md-virtual-repeat-container .md-virtual-repeat-offsetter {
padding-left: 16px;
}
script.js
angular.module('feed', ['ui.router', 'ngMaterial']);
angular.module('feed').run(
['$rootScope', '$state', '$stateParams',
function($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}
]
)
.config(
['$stateProvider', '$urlRouterProvider', '$locationProvider',
function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$stateProvider
.state('posttest', {
url: '/post1',
templateUrl: 'template.html',
resolve: {
data: 'vm.data',
},
controller: 'PostController'
});
}
]
);
// This is how I normally fetch a feed page. (PostData factory)
// I commented out this part and tried to inregrate it below at PostController section.
/*
angular.module('feed').factory('PostData', ["$http", function($http) {
return $http.get("/feed/1").then(function(response) {
return response.data;
});
}]);
*/
// This is the part I couldn't inregrate it.
// Original link is here : https://material.angularjs.org/latest/demo/virtualRepeat
// I'm trying to implement Infinite Scroll, a demo can be seen below
// http://codepen.io/anon/pen/NxeVwo
angular.module('feed').controller('PostController', ['$scope', '$http', function($scope, $http, $timeout) {
var vm = this;
vm.data = {
numLoaded_: 0,
toLoad_: 0,
items: [],
// Required.
getItemAtIndex: function(index) {
if (index > this.numLoaded_) {
this.fetchMoreItems_(index);
return null;
}
return this.items[index];
},
// Required.
getLength: function() {
return this.numLoaded_ + 1;
},
fetchMoreItems_: function(index) {
if (this.toLoad_ < index) {
this.toLoad_ += 1;
$http.get('/feed/' + this.toLoad).then(angular.bind(this, function(response) {
this.items = this.items.concat(response.data);
this.numLoaded_ = this.toLoad_;
}));
}
}
};
}]);

Error: [$parse:syntax] and home.html 404 (Not Found)

I began following a tutorial to AngularJs today, but implementing something slightly different, now I'm stuck, seems that Angular is not recognizing the inline template "home".
P.S: To run this locally on chrome I had to install a webserver.
angular.module('little_tweet', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl'
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl'
});
$urlRouterProvider.otherwise('home');
}])
.factory('posts', [function() {
var o = { posts: []};
return o;
}])
.controller('MainCtrl', ['$scope', 'posts', function($scope, posts){
$scope.posts = posts.posts;
$scope.current_user = 'me';
$scope.addPost = function() {
if(!$scope.message || $scope.message === '') { return; }
$scope.posts.push({
user: $scope.current_user,
message: $scope.message,
time: new Date()
});
$scope.message = '';
};
}])
.controller('PostsCtrl', ['$scope', '$stateParams', 'posts', function($scope, $stateParams, posts) {
$scope.post = posts.posts[$stateParams.id];
}]);
<html>
<head>
<title>Little Tweet</title>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="app.js"></script>
<style> .glyphicon-thumbs-up { cursor:pointer } </style>
</head>
<body ng-app="little_tweet">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
<div class="page-header">
<h1>Little Tweet</h1>
</div>
<div ng-repeat="post in posts">
<span style="font-size:20px; margin-left:10px;">
{{{post.user}}: {{post.message}} at {{post.time}}
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Message"
ng-model="message"></input>
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Little tweet</h1>
</div>
<!-- rest of template -->
</script>
</body>
</html>
Remove the / from template url in routes.
EDIT
there is an extra { in {{{post.user}}: {{post.message}} at {{post.time}}.

ngAnimate causes element.css ('display','block') failure when reloading the route

This example is injected into the ngAnimate.
First, you need to visit this test page like "/#/test/1" , 3 seconds after the modified $location.path ('/test/2'), the controller is re loaded,but the floating layer can not be displayed (box.css('display', 'block') failure).
If you do not inject ngAnimate, everythings is ok, the floating layer can be displayed.
I don't know what's going on, it's a bug ngAnimate?
HTML:
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<title>test</title>
<style type="text/css">
.popup {
position: fixed; width: 100%; height: 100%; background-color: rgba(36,36,36,.96); top: 0; left: 0; z-index: 1;
}
.popup .context .hd {
font-size: 32px; color:#FFF; text-align: center;
}
.popup .close {
font-size: 32px; color:#999; text-align: center;
}
</style>
</head>
<body>
<div class="wrapper" ng-view></div>
<script src="angular_1.4.1.min.js" type="text/javascript"></script>
<script src="angular-route.min.js" type="text/javascript"></script>
<script src="angular-animate.min.js" type="text/javascript"></script>
</body>
</html>
template demo.html
route : <span style="color:red; font-size: 32px;">{{id}}</span>
<input type="button" pop-window-open ng-click="openPopWindow()" style="width:200px; height: 50px;" value="open window">
<section class="popup" id="popWindow" style="display: none;">
<div class="context">
<div class="hd">pop window</div>
<div class="bd"></div>
</div>
<div class="close" pop-window-close ng-click="closePopWindow()">close</div>
</section>
javascript:
angular.module('app', ['ngRoute', 'ngAnimate', 'youyuApp.controllers', 'youyuApp.directives'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/test/:id', {
templateUrl : 'demo.html',
controller : 'ctrl1'
});
}]);
angular.module('youyuApp.controllers', [])
.controller('ctrl1', ['$scope', '$location', '$timeout', '$routeParams',
function($scope, $location, $timeout, $routeParams) {
$scope.id = $routeParams.id;
$timeout(function() {
$location.path('/test/2');
}, 3000);
}]);
angular.module('youyuApp.directives', [])
.directive('popWindowOpen', function() {
return {
restrict: 'EA',
link : function(scope, element, attrs) {
var box = angular.element(document.getElementById('popWindow'));
scope.openPopWindow = function() {
box.css('display', 'block');
};
}
}
})
.directive('popWindowClose', function() {
return {
restrict: 'EA',
scope : true,
link : function(scope, element, attrs) {
var box = angular.element(document.getElementById('popWindow'));
scope.closePopWindow = function() {
box.css('display', 'none');
};
}
}
})

How to get AngularJS routing to maintain state?

I'm getting up to speed with AngularJS routing and have created this example which works.
However, I understood that if on page "home" I type in a text into the input box, then click on page "about" and then come back to "home", the text would still be in the input box, i.e. would have maintained the state.
Is this not the case, and if not, is there a way to maintain state in forms on pages which the user navigates away from?
home.htm
<div class="jumbotron">
<h1>Home</h1>
<p>{{subtitle}}</p>
</div>
<input ng-model="message"/>
index.htm
<html ng-app="mainApp">
<head>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" rel="stylesheet" />
<style type="text/css">
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
a:focus {
outline: none;
}
</style>
</head>
<body ng-cloak ng-controller="mainController">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<div class="navbar-brand">AngularJS Routing</div>
</div>
<div>
<ul class="nav navbar-nav">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
</div>
</div>
</nav>
<div class="col-lg-12">
<div ng-view></div>
</div>
<script>
var mainApp = angular.module('mainApp', ['ngRoute']);
mainApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.htm',
controller: 'mainController'
})
.when('/about', {
templateUrl: 'pages/about.htm',
controller: 'aboutController'
})
.when('/contact', {
templateUrl: 'pages/contact.htm',
controller: 'contactController'
})
.otherwise({
redirectTo: '/'
});
});
mainApp.controller('mainController', function ($scope) {
$scope.subtitle = 'the home page';
$scope.message = '';
});
mainApp.controller('aboutController', function ($scope) {
$scope.subtitle = 'the about page';
});
mainApp.controller('contactController', function ($scope) {
$scope.subtitle = 'the contact page';
});
</script>
</body>
</html>
Controllers do not maintain state, they are created and destroyed every time you go through the route. You will need to implement a service that you can use to store your data and then have a means to send the data to the service when you want to persist it. Controller have a '$destroy' event that occurs right before the scope is released that you can hook.
mainApp.service('myData', function() {
this.message = '';
})
.controller('mainController', function($scope, myData) {
$scope.message = myData.message;
$scope.$on("$destroy", function() {
myData.message = $scope.message;
});
});

Resources