I am currently developing a chat web app. This should be realized as a single page app. For this I use Angular Router. I use socket-io to send the messages from the client to the server. Navigating between the routes actually works quite well.
In the route home.html, there is an input element for entering the message. After clicking the button, it will be added as an <li> element in the <ul> list and displayed. When starting the app, I can write messages normally. But if I navigate from the home route to another route and then go back to home and enter the message, it will be sent twice. The next time you navigate back and forth then three times, and so on. As if the controller is running several times.
I cannot find a solution to this problem on the internet. But that has to go anyway.
P.S: I have only included a script file in index.html, because I use gulp to put all the js files together in one file.
Here is the code.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
<title>FB4 Messenger</title>
<meta name="viewport" content="width=device-width, user-scalable=xo, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="css/style.css">
</head>
<body ng-app="chatApp">
<div class="loader">
<div class="loader-text">Laden...</div>
<div class="progress">
<div class="progress-bar progress-bar-danger progress-bar-striped active" role="progressbar" style="width: 100%"></div>
</div>
<!--progress-->
</div>
<!--loader-->
<header>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data- toggle="collapse" data-target="#collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<section class="layout">
<div class="branding">
<a href="/">
<img src="images/header/app_fh_logo.png" alt="App logo">
</a>
</div>
<!--branding-->
</section>
<!--layout-->
</div>
<!--navbar-header-->
</div>
<div class="collapse navbar-collapse" id="collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">
<a href="/">
<span class="glyphicon glyphicon-home"></span>
Startseite
</a>
</li>
<li>
<a href="/profile">
<span class="glyphicon glyphicon-user"></span>
Konto
</a>
</li>
<li>
<a href="/about">
<span class="glyphicon glyphicon-info-sign"></span>
Über
</a>
</li>
</ul>
</div>
<!-- navbar collapse -->
</nav>
</header>
<!--header-->
<!-- ANGULAR DYNAMIC CONTENT -->
<div ng-view></div>
<script src="js/script.js"></script>
</body>
</html>
home.html
<div class="container">
<ul id="messages"></ul>
<div>
<input id="m" ng-model="message" autocomplete="off" />
<button id="send" ng-click="send()">Send</button>
</div>
</div>
about.html
<div class="container">
<div class="card">
<img class="card-img-top" src="../images/header/app_fh_logo.png" alt="Card image cap">
<div class="card-body">
<h3 class="card-title">FB4 Messenger</h3>
<p class="card-text">Version: 0.0.1 </br> Ⓒ </p>
Startseite
</div>
</div>
</div>
app.js
let $ = jQuery = require("jquery");
require("./bootstrap.min");
require("angular");
require("angular-route");
angular.module("chatApp", ["ngRoute", "appRoutes", "MainCtrl", "ProfileCtrl", "AboutCtrl"]);
$(function() {
$(".loader").fadeOut(1000);
});
appRoutes.js
angular.module("appRoutes", []).config(["$routeProvider", "$locationProvider",
function($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: "views/home.html",
controller: "MainController"
})
.when("/profile", {
templateUrl: "views/profile.html",
//controller: "ProfileController"
})
.when("/about", {
templateUrl: "views/about.html",
//controller: "AboutController"
});
$locationProvider.html5Mode(true);
}
]);
mainCtrl.js (here the message is sent to the server)
angular.module("MainCtrl", []).controller("MainController", ["$scope",
function ($scope) {
let io = require("socket.io-client");
let socket = io.connect();
$scope.send = function () {
socket.emit("message", $scope.message);
$scope.message = "";
};
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
socket.on("message", function (m) {
let $li = $("<li>").text(m);
$("#messages").append($li);
});
}
]);
And the Server, index.js that receives the messages
const express = require("express");
const http = require("http");
let app = express();
let server = http.createServer(app);
app.use(express.static(__dirname + "/"));
app.get("*", function (req, res){
res.sendFile(__dirname+"/index.html");
});
let io= require("socket.io")(server);
io.on("connection", function (socket) {
socket.on("message", function (m) {
io.emit("message", m);
console.log(m);
});
});
server.listen(3000, function () {
console.log("Server runing");
});
This is problem.
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
Everytime your controller loads this is attached to the body as a new function. So it triggers everytime the same function call.
I suggest you could use this
$("body").removeAttr("keypress");
$("body").keypress(function (event) {
if (event.keyCode === 13) {
$("#send").click();
}
});
Better yet, use ng-click/ng-keyup and provide a function in scope
// home.html
ng-keyup="$event.keyCode == 13 && vm.sendFn()"
// in controller
vm.sendFn=function(){
... code ...for ..send
}
Edited
Can you change MainController this way and try.
It probably happens because of something similar to this -
https://github.com/angular-fullstack/generator-angular-fullstack/issues/490
let io = require("socket.io-client");
let socket = io.connect();
socket.on("message", function (m) {
let $li = $("<li>").text(m);
$("#messages").append($li);
});
angular.module("MainCtrl", []).controller("MainController", ["$scope",
function ($scope) {
$scope.send = function () {
socket.emit("message", $scope.message);
$scope.message = "";
};
}
]);
Related
I have a directive in my angular website that builds a page header, in that page header I am wanting to show the user's first and last name. I am wrapping my entire application in a MainController. My rendered HTML looks like this,
<html ng-app="app" ng-controller="MainController as main" class="fa-events-icons-failed ng-scope">
<head>
<style type="text/css">#charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>
<meta charset="utf-8">
<title ng-bind="main.windowTitle" class="ng-binding">App School Management</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="dist/css/generic.css">
<link rel="stylesheet" type="text/css" href="dist/css/styles.min.css">
<script src="https://use.fontawesome.com/2a6c262d81.js"></script><script src="https://cdn.fontawesome.com:443/js/stats.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/2a6c262d81.css" media="all">
</head>
<body cz-shortcut-listen="true">
<div id="page-wrapper">
<div id="page-header" class="bg-gradient-9 ng-isolate-scope" header="" user="userModel">
<div id="mobile-navigation">
<button id="nav-toggle" class="collapsed" data-toggle="collapse" data-target="#page-sidebar"><span></span></button>
</div>
<div id="header-logo" class="logo-bg">
<a ui-sref="dashboard.home" class="branding" title="Schoozle">
App Logo
</a>
<a id="close-sidebar" href="#" title="Close sidebar">
<i class="fa fa-chevron-left" aria-hidden="true"></i>
</a>
</div>
<div id="header-nav-left">
<div class="user-account-btn dropdown">
<a href="#" title="My Account" class="user-profile clearfix" data-toggle="dropdown">
<img width="28" src="http://placehold.it/40x40" alt="Profile image">
<span ng-bind="$scope.user.first_name" class="ng-binding"></span>
<i class="fa fa-chevron-down" aria-hidden="true"></i>
</a>
</div>
</div>
<!-- #header-nav-left -->
<div id="header-nav-right">
<div class="dropdown" id="notifications-btn">
<a data-toggle="dropdown" href="#" title="">
<span class="small-badge bg-yellow"></span>
<i class="fa fa-bell" aria-hidden="true"></i>
</a>
<div class="dropdown-menu box-md float-right">
<!-- Notifications Dropdown -->
</div>
</div>
</div>
</div>
My non directive HTML looks like this,
<div header user="userModel"></div>
And my controller code, and directive code looks this,
app.directive('header', [function () {
return {
restrict: 'A', //This menas that it will be used as an attribute and NOT as an element. I don't like creating custom HTML elements
replace: true,
scope: {user: '='}, // This is one of the cool things :). Will be explained in post.
templateUrl: "/templates/partials/header.html",
controller: ['$scope', '$filter', function ($scope, $filter) {
// Your behaviour goes here :)
}]
}
}]);
app.controller('MainController', ['$scope', 'UserService', function($scope, UserService){
var self = this;
this.windowTitle = "App School Management";
this.loading = true;
this.user = {};
UserService.authenticatedUser()
.then(function(response){
self.loading = false;
self.userModel = response.message;
}, function(error) {
self.hasError = true;
self.errors = error.message;
});
}]);
How do I get my user object from the controller into the directive?
Since you are using MainController as main, add main to your directive:
<div header user="main.userModel"></div>
than user data will be available through your isolated scope two way binding within your 'templates/partials/header.html' as user object, something like user.firstName and user.lastName.
You can avoid using $scope by adding to your directive definition
controllerAs: 'ctrl';
bindToController: true;
than your user data will be available witin HTML as ctrl.user object
I'm newbie to Angular js..But try to make an image slider in my file..
And also I'm using route..Acutally I'm having three pages..
1.home
2.about
3.contact
For this I create an index file in which I add header and footer
While I'm adding the slider in my index page it works fine for me..
But if I did the same thing in my home page..It won't work and I din't find any errors in my console also..
I don't know how to fix it..
Here I attach my all codes..
script.js
// create the module and name it scotchApp
var scotchApp = angular.module('scotchApp', ['ngRoute','ngAnimate', 'ngTouch']);
// configure our routes
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'homeController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function($scope) {
//Logo
$scope.logo = 'logo.png';
//username
$scope.username = 'Jonathan Stephanopalus';
//footercontent
$scope.footer = [
{ title: 'Contacts' },
{ title: 'Feedback' },
{ title: 'Help' },
{ title: 'Site Map' },
{ title: 'Terms & Conditions' },
{ title: 'Privacy Statement' },
{ title: 'Cookie Policy' },
{ title: 'Trademarks' }
];
});
scotchApp.controller('homeController', function($scope) {
// create a message to display in our view
$scope.message = "Lorem Ipsum ";
//lastdiv
$scope.lastdiv = { image : "women_wright.png" ,title:"Get to know Cisco better: Community Forums"};
//slider
$scope.slides = [
{image: 'images/img00.jpg', description: 'Image 00'},
{image: 'images/img01.jpg', description: 'Image 01'},
{image: 'images/img02.jpg', description: 'Image 02'},
{image: 'images/img03.jpg', description: 'Image 03'},
{image: 'images/img04.jpg', description: 'Image 04'}
];
$scope.direction = 'left';
$scope.currentIndex = 0;
$scope.setCurrentSlideIndex = function (index) {
$scope.direction = (index > $scope.currentIndex) ? 'left' : 'right';
$scope.currentIndex = index;
};
$scope.isCurrentSlideIndex = function (index) {
return $scope.currentIndex === index;
};
$scope.prevSlide = function () {
$scope.direction = 'left';
$scope.currentIndex = ($scope.currentIndex < $scope.slides.length - 1) ? ++$scope.currentIndex : 0;
};
$scope.nextSlide = function () {
$scope.direction = 'right';
$scope.currentIndex = ($scope.currentIndex > 0) ? --$scope.currentIndex : $scope.slides.length - 1;
};
});
scotchApp.animation('.slide-animation', function () {
return {
beforeAddClass: function (element, className, done) {
var scope = element.scope();
if (className == 'ng-hide') {
var finishPoint = element.parent().width();
if(scope.direction !== 'right') {
finishPoint = -finishPoint;
}
TweenMax.to(element, 0.5, {left: finishPoint, onComplete: done });
}
else {
done();
}
},
removeClass: function (element, className, done) {
var scope = element.scope();
if (className == 'ng-hide') {
element.removeClass('ng-hide');
var startPoint = element.parent().width();
if(scope.direction === 'right') {
startPoint = -startPoint;
}
TweenMax.fromTo(element, 0.5, { left: startPoint }, {left: 0, onComplete: done });
}
else {
done();
}
}
};
});
scotchApp.controller('aboutController', function($scope) {
$scope.message = 'Look! I am an about page.';
});
scotchApp.controller('contactController', function($scope) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
home.html
<div ng-controller="homeController">
<div class="container slider">
<img ng-repeat="slide in slides" class="slide slide-animation nonDraggableImage" ng-swipe-right="nextSlide()" ng-swipe-left="prevSlide()" ng-hide="!isCurrentSlideIndex($index)" ng-src="{{slide.image}}">
<a class="arrow prev" href="#" ng-click="nextSlide()"></a>
<a class="arrow next" href="#" ng-click="prevSlide()"></a>
<nav class="nav">
<div class="wrapper">
<ul class="dots">
<li class="dot" ng-repeat="slide in slides">
{{slide.description}}
</li>
</ul>
</div>
</nav>
test
</div>
</div>
index.html
<!DOCTYPE html>
<!-- define angular app -->
<html ng-app="scotchApp">
<head>
<!-- SCROLLS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
<!-- <link rel="stylesheet" href="styles/main.css" /> -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" />
<!-- <link href="css/bootstrap.css" rel="stylesheet"> -->
<link rel="stylesheet" href="css/styles.css">
<!-- <script src="js/app.js"></script> -->
<!-- SPELLS -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-touch.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.10.3/TweenMax.min.js"></script>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script> -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="script.js"></script>
</head>
<!-- define angular controller -->
<body class="angular_class" ng-controller="mainController">
<nav class="navbar navbar-default">
<div class="container">
<div class="menu_1">
<div class="navbar-header">
<a class="navbar-brand" href="/"><img src="image/{{logo}}"></a>
</div>
<div class="f_right">
<p>Welcome, {{ username }}</p>
<img src="image/sml_logo.png">
</div>
</div>
<div class="menu_1">
<ul class="nav navbar-nav navbar-left">
<li ng-repeat="teams in teamArray">{{ teams.team_name }}</li>
</ul>
<div class="f_right">
<input type="text" class="searchbox" placeholder="Search"></input>
</div>
</div>
</div>
</nav>
<div id="main">
<!-- angular templating -->
<!-- this is where content will be injected -->
<div ng-view></div>
</div>
<footer class="text-center">
<div class="footer_block">
<span ng-repeat="ft in footer">{{ ft.title }}</span>
</div>
</footer>
</body>
</html>
And for information I follow this link
Could someone please help me out of this..
Thank you,
Change home.html
<div ng-controller="homeController">
<div class="container slider">
<img ng-repeat="slide in slides" class="slide slide-animation nonDraggableImage" ng-swipe-right="nextSlide()" ng-swipe-left="prevSlide()" ng-hide="!isCurrentSlideIndex($index)" ng-src="{{slide.image}}">
<a class="arrow prev" href="#" ng-click="nextSlide()"></a>
<a class="arrow next" href="#" ng-click="prevSlide()"></a>
<nav class="nav">
<div class="wrapper">
<ul class="dots">
<li class="dot" ng-repeat="slide in slides">
{{slide.description}}
</li>
</ul>
</div>
</nav>
test
</div>
with
<div class="container slider">
<img ng-repeat="slide in slides" class="slide slide-animation nonDraggableImage" ng-swipe-right="nextSlide()" ng-swipe-left="prevSlide()" ng-hide="!isCurrentSlideIndex($index)" ng-src="{{slide.image}}">
<a class="arrow prev" href="#" ng-click="nextSlide()"></a>
<a class="arrow next" href="#" ng-click="prevSlide()"></a>
<nav class="nav">
<div class="wrapper">
<ul class="dots">
<li class="dot" ng-repeat="slide in slides">
{{slide.description}}
</li>
</ul>
</div>
</nav>
test
</div>
I am new to angular js and following this tutorial http://embed.plnkr.co/dd8Nk9PDFotCQu4yrnDg/ for creating simple SPA page. In which, When I use Local and Session storage concepts in About page ,It is perfectly working in Firefox,IE except Chrome. I am not able to find the problem in Chrome. So Please need your help.
index.html
<html ng-app="scotchApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/ngstorage/0.3.6/ngStorage.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="./script.js" type="text/javascript"></script>
</head>
<body ng-controller="mainController">
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Angular Routing Example</a>
</div>
<ul class="nav navbar-nav navbar-right">
<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>
</nav>
</header>
<!-- MAIN CONTENT AND INJECTED VIEWS -->
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
pages/about.html:
<div class="jumbotron text-center">
<h1>About Page</h1>
<p>{{ message }}</p>
<input type="button" value="Save" ng-click="Save()" />
<input type="button" value="Get" ng-click="Get()" />
</div>
pages/contact.html:
<div class="jumbotron text-center">
<h1>Contact Page</h1>
<p>{{ message }}</p>
</div>
pages/home.html:
<div class="jumbotron text-center">
<h1>Home Page</h1>
<p>{{ message }}</p>
</div>
scripts.js:
var scotchApp = angular.module('scotchApp',['ngRoute','ngStorage']);
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function($scope, $localStorage, $sessionStorage, $window) {
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
scotchApp.controller('aboutController', function($scope, $localStorage, $sessionStorage, $window) {
$scope.message = 'Look! I am an about page.';
$scope.Save = function () {
$localStorage.LocalMessage = "LocalStorage: My name is Mudassar Khan.";
$sessionStorage.SessionMessage = "SessionStorage: My name is Mudassar Khan.";
$localStorage.$save();
$sessionStorage.$save();
}
$scope.Get = function () {
$window.alert($localStorage.LocalMessage + "\n" + $sessionStorage.SessionMessage);
}
});
scotchApp.controller('contactController', function($scope, $localStorage, $sessionStorage, $window) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
Thanks In advance.
you need to serve your html via a local server .
Now Your files are being served as file:/// it should be http://
refer this stackoverflow answer
I followed tutorial on this LINK to create AJAX requests on my angularJS appliction (CRUD operations). After I finished coding I tried to perform AJAX request (get all data from database) but when I lunch my application I got this error:
TypeError: undefined is not a function
at new <anonymous> (http://localhost:49510/Scripts/application/controllers.js:4:15)
Does someone knows where's the problem and how to fix it?
Here is code:
controller:
app.controller('ContactsController', [
'$scope', '$http', '$location', 'contactsService',
function ($scope, $location, $http, contactsService) {
$http.get('/contacts/').success(function (data) { //triggers error
alert(data);
$scope.contact = data;
$scope.loading = false;
})
.error(function () {
alert ("An Error has occured while loading contacts!");
// $scope.loading = false;
});
$scope.editContact = function (id) {
$location.path('/edit-contact/' + id);
};
$scope.displayContact = function (id) {
$location.path('/display-contact/' + id);
};
$scope.showDetails = function (id) {
var el = angular.element(document.getElementById('#ct-details-' + id));
el.toggleClass('details-hidden');
}
}
]);
and here is contacts.html template:
<div class="container view">
<header>
<h3>Contacts</h3>
</header>
<div>
<a class="nav-pills hover" href="#/add-contact">Add Contact</a>
</div>
<br /><br />
<div class="row">
<ul class="span5" >
<li class="nav-pills nav-stacked contact-row" data-ng-repeat="contact in contacts | orderBy:'firstName'">
<span id="ct-details-{{contact.id}}" data-ng-click="displayContact(contact.id)" style="cursor:pointer;" class="contact-data details-hidden" href="" >
<span class="span3 contact-name" >{{contact.firstName + ' ' + contact.lastName}}
{{contact.emailAddress}}</span>
</span>
<button class="btn editContact" data-ng-click="deleteContact(contact.id)">Delete</button>
<button class="btn editContact" data-ng-click="editContact(contact.id)">Edit</button>
</li>
</ul>
</div>
</div>
and here is index.cshtml file:
<!DOCTYPE html>
<html ng-app="contactsManager">
<head>
<title>Contacts</title>
</head>
<body>
<div class="navbar navbar-top">
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/custom.css" rel="stylesheet" />
<div class="navbar-inner">
<div class="container">
<h2>Contacts</h2>
</div>
</div>
</div>
<div ng-view class="example-animate-container"
ng-animate="{enter: 'example-enter', leave: 'example-leave'}"></div>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/application/application.js"></script>
<script src="~/Scripts/application/controllers.js"></script>
<script src="~/Scripts/application/contactsService.js"></script>
</body>
</html>
The order of arguments in the controller function has to match the order in the parameter array.
You have mixed the order of $http and $location.
So change your function signature to
app.controller('ContactsController', [
'$scope', '$http', '$location', 'contactsService',
function ($scope, $http, $location, contactsService) {
Here is a small self-contained html todo application using routes...
It has two views - list.html and add.html
list.html:
<div>
Add Task
<br />
<br />
<div class="container" id="tasks">
<ul>
<li ng-repeat="task in tasks">
<button ng-show="!task.done" ng-click="markTaskAsDone(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-ok-circle"></span></button>
<button ng-show="task.done" ng-click="markTaskAsNotDone(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-pushpin"></span></button>
<button ng-click="removeTask(task)" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-remove-circle"></span></button>
<s ng-show="task.done">{{task.desc}}</s>
<span ng-show="!task.done">{{task.desc}}</span>
</li>
</ul>
<p ng-show="tasks.length == 0">Add few tasks</p>
</div>
</div>
add.html:
<div>
<span class="glyphicon glyphicon-arrow-left"></span> Back
<h2>Add a task</h2>
<div class="form-inline">
<input type="text" data-ng-model="newTask.desc" placeholder="Enter Task..." class="form-control" />
Add
</div>
</div>
I only have one controller.
controllers = {
ToDoController: function ($scope, $timeout, $location) {
//two items in by default...
$scope.tasks = [
{ desc: 'Buy milk', done: false },
{ desc: 'Collect newspaper', done: false }
];
$scope.newTask = { desc: '', done: false };
$scope.addNewTask = function () {
$location.path('/');
console.log('a');
$scope.tasks.push($scope.newTask);
}
$scope.markTaskAsDone = function (task) {
task.done = true;
console.log($scope.tasks);
}
$scope.markTaskAsNotDone = function (task) {
task.done = false;
};
$scope.removeTask = function (task) {
$scope.tasks.splice($scope.tasks.indexOf(task), 1);
};
//called to set newTask
$scope.setNewTask = function () {
$scope.newTask = { desc: '', done: false };
};
}
};
My shell page looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ToDo List</title>
<!-- Bootstrap -->
<link href="Content/bootstrap.min.css" rel="stylesheet">
<link href="Content/bootstrap-theme.min.css" rel="stylesheet">
<style>
#tasks ul {
margin: 0px;
padding: 0px;
list-style: none;
font-size: large;
}
</style>
</head>
<body>
<h1>TODO App</h1>
<div data-ng-app="todoApp">
<div data-ng-view=""></div>
</div>
<script src="Scripts/jquery-1.9.0.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/todo.js"></script>
<script>
var app = angular.module('todoApp', ['ngRoute']);
app.controller(controllers);
app.config(function ($routeProvider) {
$routeProvider
.when('/list', {
controller: 'ToDoController',
templateUrl: 'partials/list.html'
})
.when('/add', {
controller: 'ToDoController',
templateUrl: 'partials/add.html'
})
.otherwise({ redirectTo: '/list' });
});
</script>
</body>
</html>
Issue:
When I load index.html its shows the list.html. The two default items I've put shows up. I click on Add and navigate to the second view (add.html), enter details and click on the Add button in that page...I navigate to the list.html view, but its still showing the old list...not the updated list...
Surely missing some api call to do the update to the view...else this page is coming from some cache. What is the correct way to do this?
ToDoController is instantiated twice and separately for your two views. To maintain 1 instance of the controller to control both views, don't declare it in your routing, but declare it on a parent tag of the views.
For instance, like this:
<div data-ng-app="todoApp" data-ng-controller="ToDoController">
<div data-ng-view></div>
</div>
Even better is to write separate controllers for each view to put the view-specific logic into, and have 1 parent controller to store values that both controllers should have access to.
Another way to share scope among isolated controllers is using $rootScope, but you should normally try to avoid using that (like you would try to avoid using global variables in any programming language).