I am having difficulties combining both the editing of a current contact and the creation of a new contact. I am able to edit the contact that I click on, however, when I try and click on add new address the following error message -
angular.js:13424 Error: [$injector:unpr] http://errors.angularjs.org/1.5.3/$injector/unpr?p0=editIndexProvider%20%3C-%20editIndex%20%3C-%20ModalCtrl
This is due to using resolve based on the answer here
Factory
'use strict';
var app = angular.module('testApp', ['ngRoute','ui.bootstrap']);
app.factory('addressFactory', function(){
var addressFactory = {};
addressFactory.addressBook = [];
addressFactory.saveAddress = function(name, address){
addressFactory.addressBook.push({
name: name,
address: address
});
};
addressFactory.updateAddress = function(name, address, index){
addressFactory.addressBook[index] = {
name: name,
address: address
};
};
return addressFactory;
})
CONTROLLERS
.app.controller('testCtrl', ['$uibModal', 'addressFactory', function ($uibModal, addressFactory) {
var testCtrl = this;
this.addressBook = addressFactory.addressBook;
this.open = function () {
touchnoteCtrl.modalInstance = $uibModal.open({
templateUrl: 'app/views/partials/add-address.html',
controller: 'ModalCtrl',
controllerAs:'ctrl'
});
}
this.openEdit = function(index) {
touchnoteCtrl.modalInstance = $uibModal.open({
templateUrl: 'app/views/partials/edit-address.html',
controller: 'ModalCtrl',
controllerAs:'ctrl',
resolve: {
editIndex: function () {
return index;
}
}
});
}
}])
.controller('ModalCtrl', ['$uibModalInstance','addressFactory','editIndex', function ($uibModalInstance,addressFactory, editIndex) {
this.addressBook = addressFactory.addressBook;
this.saveAddress = function( name, address) {
addressFactory.saveAddress( name, address);
$uibModalInstance.dismiss('cancel');
}
this.getIndex = editIndex;
console.log(this.getIndex)
this.updateAddress = function(name, address, index) {
addressFactory.updateAddress( name, address, index);
}
this.cancelAddress = function () {
$uibModalInstance.dismiss('cancel');
};
}]);
HTML
home.html
<a ng-click="ctrl.open()">Enter new address</a>
<div ng-repeat="contact in ctrl.addressBook track by $index">
<p class="contactName">{{contact.name}}</p>
<p class="contactAddress">{{contact.address}}</p>
<button ng-click="ctrl.openEdit($index)">Edit Contact</button>
</div>
form.html
<form>
<input ng-model="ctrl.name" type="text">
<input ng-model="ctrl.address" type="text">
</form>
edit-address.html
<h3>Edit address</h3>
<div ng-include="'app/views/partials/form.html'"></div>
<div>
<button ng-click="ctrl.cancelAddress()">Cancel</button>
<button ng-click="ctrl.updateAddress(ctrl.name, ctrl.address, ctrl.getIndex)">Save</button>
</div>
add-address.html
<h3>Add address</h3>
<div ng-include="'app/views/partials/form.html'"></div>
<div>
<button ng-click="ctrl.cancelAddress()">Cancel</button>
<button ng-click="ctrl.addAddress(ctrl.name, ctrl.address)">Save</button>
</div>
You use the same ModalCtrl for both the open and the openEdit function. The open function does not have a resolve parameter. This way, angular cannot resolve the injected editIndex. Try this:
this.open = function () {
touchnoteCtrl.modalInstance = $uibModal.open({
templateUrl: 'app/views/partials/add-address.html',
controller: 'ModalCtrl',
controllerAs:'ctrl',
resolve: {
editIndex: function () {
return undefined;
}
}
});
}
I think you simply miss a module dependency to angular.ui.bootstrap...
Related
This question already has answers here:
Why are Callbacks from Promise `.then` Methods an Anti-Pattern
(2 answers)
Closed 5 years ago.
I am adding a simple todo list to my ionic vs1/angularjs project.
I want to use the ionic modal to launch this list. Since I need to launch it from everywhere I looked for a way to do this.
I found this article https://medium.com/#saniyusuf/create-an-isolate-modal-with-ionic-v1-b4cf73f05727 which had me create a factory that could be launched from any controller. Love it!
Problem is, it's a todo list where users need to be able to add/delete.
I want to save this information to firebase so I created a factory to hold all the firebase crud operations for the ToDo list.
So I now have a factory that launches the modal and one that has the firebase crud operations.
In the modal launcher I figured out how to include the crud operations so that the buttons would interact. Problem is how do I get the value of the input.
Modal Launcher
angular.module('formulaWizard')
.factory('IsolateModal', IsolateModal)
IsolateModal.$inject = ['$rootScope', '$ionicModal', '__ToDo',
'$window'];
function IsolateModal($rootScope, $ionicModal, __ToDo, $window) {
var modalsIsolateScope = $rootScope.$new();
var currentUser = $rootScope.currentUser || JSON.parse($window.sessionStorage.getItem('payload'));
var isolateModal = {
open: open
};
function open() {
$ionicModal.fromTemplateUrl(
'app/to-do/toDo.html',
{
scope: modalsIsolateScope
}
)
.then(function (modalInstance) {
modalsIsolateScope.close = function () {
closeAndRemove(modalInstance);
},
modalsIsolateScope.add = function(){
addTodo(modalInstance);
};
return modalInstance.show();
});
}
function closeAndRemove(modalInstance) {
return modalInstance.hide()
.then(function () {
return modalInstance.remove();
});
}
function addTodo(modalInstance) {
var i = modalInstance
__ToDo.toDo($scope.input)
.then(function(result) {
$scope.input = {};
// Reload our todos, not super cool
getAllTodos();
});
}
return isolateModal;
}
My Data Factory
angular.module('formulaWizard')
.factory('__ToDo', function(__Refs, $q) {
return {
toDo: function(id, userObject, cb) {
var toDo = __Refs.userNotes.child(id).push(userObject);
__Refs.userNotes.child(id).child(newToDo.key()).update({ toDo_id:
newToDo.key() }).then(function(response) {
cb(response);
}, function(e) {
console.error('error occured');
});;
},
updateToDo: function(userId, toDoId, userObject, cb) {
var x =
__Refs.userNotes.child(userId).child(toDoId).update(userObject)
.then(function(response) {
cb(response);
}, function(e) {
console.error('Error editing');
});
},
deleteToDo: function(userId, toDoId, cb) {
__Refs.userNotes.child(userId).child(toDoId).remove(function(error) {
if (error) {
console.error(error);
} else {
cb();
}
});
},
getuserNotes: function(id, cb) {
__Refs.userNotes.child(id).on('value', function(response) {
cb(response.val());
});
}
}
});
Call From Controller
$scope.openModal = function () {
IsolateModal.open();
};
Html
<ion-modal-view>
<ion-header-bar class="bar-stable">
<h1 class="title">My List</h1>
<button class="button icon ion-close-round button-icon"
ng-click="close()"></button>
</ion-header-bar>
<ion-content>
<div class="list card" style="width:100%; margin-left:0;">
<div class="item item-body">
<div class="item-input-inset">
<label class="item-input-wrapper">
<input id="newInput" type="text" placeholder="New Todo"
ng-model="input.name">
</label>
<button class="button button-balanced button-small" ng-click="add()">
Add Todo
</button>
</div>
<ion-list can-swipe="true">
<ion-item ng-repeat="item in todos">
{{item.name}}
<ion-option-button class="button-assertive" ng-click="deleteTodo(item.id)">
Delete
</ion-option-button>
</ion-item>
</ion-list>
</div>
</div>
</ion-content>
</ion-modal-view>
How can I get the input value from the html page into the factory?
Thanks
how do I get the value of the input?
Return the promise:
function open() {
̲r̲e̲t̲u̲r̲n̲ $ionicModal.fromTemplateUrl(
'app/to-do/toDo.html',
{
scope: modalsIsolateScope
}
)
.then(function (modalInstance) {
modalsIsolateScope.close = function () {
closeAndRemove(modalInstance);
},
modalsIsolateScope.add = function(){
addTodo(modalInstance);
};
return modalInstance.show();
});
}
Then extract the returned value from the promise:
$scope.openModal = function () {
var promise = IsolateModal.open();
promise.then(function(value) {
console.log(value);
});
return promise;
};
I am having an issue with ui-router and the $state.go method with params.
When clicking on a building unit while the building overview state is expanded. The buildingOverview controller is run again which then animates the overview panel again.
The weird part about this is I only have this issue while in chrome.
The panels work as intended in all other browsers.
If I adjust the url to /?buildingID or /?id the panel works as intended however, I don't get the HTML5/SEO friendly URLS.
Please see attached video and code.
https://vimeo.com/173318836
My index.route.js
(function() {
'use strict';
angular
.module('mrkb')
.config(routerConfig);
/** #ngInject */
function routerConfig($locationProvider, $stateProvider, $urlRouterProvider) {
$locationProvider.html5Mode(true);
$stateProvider
.state('building', {
abstract: true,
'url': '/bldg',
views: {
'': {
templateUrl: 'app/building/index.html',
controller: 'BuildingController as building'
},
'building-overview#building': {
templateUrl: 'app/building/overview/overview.html',
controller: 'BuildingOverviewController as buildingOverview'
},
'building-map#building': {
templateUrl: 'app/building/map/map.html',
controller: 'BuildingMapController as buildingMap'
}
}
})
.state('building.landing', {
'url': '/landing',
'': {
templateUrl: 'app/building/index.html',
controller: 'BuildingController as building'
}
})
.state('building.overview', {
'url': '/:buildingID',
views: {
'building-overview#building': {
templateUrl: 'app/building/overview/overview.html',
controller: 'BuildingOverviewController as buildingOverview',
resolve: {
init: ['BuildingResultModel', '$timeout', function(BuildingResultModel, $timeout){
if(!BuildingResultModel.expanded){
$timeout(function(){
BuildingResultModel.expanded = true;
},50);
}
}]
}
}
}
})
.state('building.detail', {
'url': '/:buildingID/:id',
views: {
'building-detail#building': {
'templateUrl': 'app/building/detail/detail.html',
'controller': 'BuildingDetailController as buildingDetail',
resolve: {
init: ['BuildingResultModel', '$timeout', function(BuildingResultModel, $timeout){
if(!BuildingResultModel.expanded && !BuildingResultModel.detailExpanded){
$timeout(function(){
BuildingResultModel.expanded = true;
BuildingResultModel.detailExpanded = true;
},50);
}
}]
}
}
}
});
$urlRouterProvider.otherwise('/bldg/landing');
}
})();
The Detail Controller
(function(){
'use strict';
angular
.module('mrkb')
.controller('BuildingMapController', BuildingMapController);
function BuildingMapController ($log, $state, BuildingResultModel, $timeout){
var vm = this;
vm.mapModel = BuildingResultModel;
vm.mapModel.currentBldgID = $state.params.buildingID;
vm.navigateToBuildingState = function(bldgNum){
if(!BuildingResultModel.expanded){
$timeout(function(){
BuildingResultModel.expanded = true;
BuildingResultModel.shiftMap = true;
}, 50);
}
BuildingResultModel.detailExpanded = false;
// reset filter by building names and plan types array
BuildingResultModel.currentBldgNames = [''];
BuildingResultModel.FloorPlanTypeAvailability = [''];
$state.go('building.overview', { buildingID:bldgNum });
};
// Navigate to landing
vm.navigateToLanding = function(event){
event.preventDefault();
BuildingResultModel.detailExpanded = false;
$timeout(function(){
BuildingResultModel.expanded = false;
BuildingResultModel.shiftMap = false;
},50);
$state.go('building.landing');
}
}
})();
Overview Controller (First Panel)
(function(){
'use strict';
angular
.module('mrkb')
.controller('BuildingOverviewController', BuildingOverviewController);
function BuildingOverviewController($log, $state, BuildingResultModel, $timeout){
var vm = this;
vm.overviewModel = BuildingResultModel;
// set BuildingResultModel for current building number to building ID passed in from state params
BuildingResultModel.currentBldgID = $state.params.buildingID;
// detail panel with building ID as param
vm.viewDetail = function(id){
$timeout(function(){
BuildingResultModel.detailExpanded = true;
},50);
$state.go('building.detail', { buildingID:BuildingResultModel.currentBldgID, id:id });
};
// Static floor plan items
vm.floorPlanItems = [
{
icon: 'icon-makoa-coaster',
name: 'Makoa',
bedroom: '3 Bedroom'
},
{
icon: 'icon-leilani-coaster',
name: 'Leilani',
bedroom: '3 Bedroom + Den'
},
{
icon: 'icon-kahua-coaster',
name: 'Kahua',
bedroom: '4 Bedroom'
}
];
// Set Active Floor Plan Filter
vm.floorPlanItemsActive = vm.floorPlanItems;
vm.setActive = function(filterItem) {
vm.floorPlanItemsActive = filterItem;
};
vm.residenceItemsActive = BuildingResultModel.allBuildings;
// Set Active Residence Unit
vm.setActiveResidence = function(id) {
vm.residenceItemsActive = id;
}
vm.AvailabiltyOptions = [
{
availability: 'available'
},
{
availability: 'sold'
},
{
availability: 'pending'
}
];
vm.filterByFloorPlan = function(name){
// Remove default class from the three floorplan filters
vm.overviewModel.filterFloorplanItemDefault = false;
BuildingResultModel.currentBldgNames = [];
BuildingResultModel.FloorPlanTypeAvailability = [''];
BuildingResultModel.currentBldgNames.push(name.toLowerCase());
};
vm.filterByAvailability = function(availability){
BuildingResultModel.FloorPlanTypeAvailability = [];
BuildingResultModel.FloorPlanTypeAvailability.push(availability);
}
vm.resetFilters = function () {
BuildingResultModel.FloorPlanTypeAvailability = [''];
}
}
})();
Map Template
<div class="mapped-item-1"
ng-class="{'active': buildingMap.mapModel.currentBldgID == 1}"
ng-click="buildingMap.navigateToBuildingState(1)">
<span class="building-text">Building</span><br />
<span class="building-number">1</span>
<div class="map-arrow"></div>
</div>
<div class="mapped-item-5"
ng-class="{'active': buildingMap.mapModel.currentBldgID == 5}"
ng-click="buildingMap.navigateToBuildingState(5)">
<span class="building-text">Building</span><br />
<span class="building-number">5</span>
<div class="map-arrow"></div>
</div>
<div class="mapped-item-2"
ng-class="{'active': buildingMap.mapModel.currentBldgID == 2}"
ng-click="buildingMap.navigateToBuildingState(2)">
<span class="building-text">Building</span><br />
<span class="building-number">2</span>
<div class="map-arrow"></div>
</div>
<div class="overlay">
</div>
<div class="map-hit-area" ng-click="buildingMap.navigateToLanding($event)"></div>
First Panel Template (Overview Panel)
<header class="building-panel-header">
<h4>Select Floorplan</h4>
</header>
<!-- Floor Plan Options Filter-->
<ul class="building-panel-floorplans">
<li ng-repeat="floorPlan in buildingOverview.floorPlanItems">
<a ng-href="#"
ng-click="buildingOverview.filterByFloorPlan(floorPlan.name); buildingOverview.setActive(floorPlan)"
ng-class="{ 'active' : buildingOverview.floorPlanItemsActive === floorPlan, default: buildingOverview.overviewModel.filterFloorplanItemDefault == true }">
<i class="icon {{floorPlan.icon}}"></i>
<span>{{floorPlan.name}}</span>
<p>{{floorPlan.bedroom}}</p>
</a>
</li>
</ul>
<!-- Units -->
<h4>Select Residences</h4>
<ul class="building-panel-units">
<li ng-repeat="building in building.buildingModel.allBuildings | filterMultipleKeyValues: {buildingID: building.buildingModel.currentBldgID, name:building.buildingModel.currentBldgNames, availability:building.buildingModel.FloorPlanTypeAvailability}">
<a href="#"
class="{{building.availability}} "
ng-class="{'active': buildingOverview.residenceItemsActive === building.id }"
ng-click="buildingOverview.viewDetail(building.id, building.name); buildingOverview.setActiveResidence(building.id);">
<i class="icon icon-{{building.name}}-coaster"></i>
<span class="building-panel-unit-number">{{building.id}}</span>
</a>
</li>
</ul>
<!-- Unit Availability Filter-->
<div class="building-panel-options">
<button ng-repeat="availabiltyOption in buildingOverview.AvailabiltyOptions"
ng-click="buildingOverview.filterByAvailability(availabiltyOption.availability)"
ng-dblclick="buildingOverview.resetFilters()"
class="btn {{availabiltyOption.availability}}">{{availabiltyOption.availability}}
</button>
</div>
I do not know what is wrong, ng-repeat is not
populating the information on my div, please look at the following
and advice where I have gone wrong
app.js
var mainApp = angular.module('mainApp', ["ngRoute", "ngResource"]);
mainApp.factory('EventListFactory',['$resource', EventListFactory]);
mainApp.controller('EventListCtrl', ['$scope','EventListFactory', EventListCtrl]);
var configFunction = function ($routeProvider) {
$routeProvider.
when('/Register', {
templateUrl: 'routesDemo/Register'
})
.when('/UpdateProfile', {
templateUrl: 'routesDemo/UpdateProfile'
})
.when('/Events', {
templateUrl: 'routesDemo/Events',
controller: EventListCtrl,
})
.when('/routeThree', {
templateUrl: 'routesDemo/three'
});
}
configFunction.$inject = ['$routeProvider'];
mainApp.config(configFunction);
EventListFactory.js
var EventListFactory = function ($resource, $location) {
var baseUrl = "";
if (window.location.hostname == 'localhost') {
baseUrl = "http://localhost:52182/api/Events/GetEvents/";
}
else
{
var deployAt = window.location.href.substring(0, window.location.href);
baseUrl = deployAt + "/api/Events/GetEvents";
}
var respone = $resource(baseUrl, null, { query: { method: 'GET', isArray: true, url: baseUrl }, get: { method: 'GET', url: baseUrl } });
console.log("api json at :" + baseUrl);
var records = respone.query();
console.log(records);
return records;
}
EventListController.js
var EventListCtrl = function ($scope, EventListFactory) {
$scope.Message = 'I work';
$scope.items = EventListFactory;
};
EventListCtrl.$inject = ['$scope'];
in the html:
<div id="listView" >
<h1 class="form-signin-heading">For real {{Message}}</h1>
<div ng-controller="EventListCtrl">
<p class="form-signin-heading">Populated Data</p>
<div ng-repeat="item in items ">
<span class="control-label">Heading : </span> {{item.Heading}}
<br/>
<span class="control-label">Event Date : </span> {{item.EventDate}}
<br/>
</div>
</div>
</div>
running the site:
api call from browser:
the code for ng-repeat is correct, but your items is an empty array so nothing gets displayed.
From the screenshots it appears that records in EventListFactory.js does not return an array but a promise.
In EventListController.js instead of
$scope.items = EventListFactory;
Try something like:
var promise = EventListFactory;
promise.then(function(data){
$scope.items = data;
})
I am trying to expose a "generic" modal - using Angular's $uibModal - through a service. Here is the definition of that service:
angular.module('app').service('CustomModalService', ['$uibModal', function ($uibModal) {
var openCustomModal = function (size, title, message) {
var actionToPerformOnConfirm = action;
var modalInstance = $uibModal.open({
templateUrl : 'templates/CustomModal.html',
size: size,
resolve: {
title: title,
message: message
}
});
};
return {
openCustomModal: openCustomModal
};
}]);
Nothing too complicated, above. However, it is not working. If I remove the resolve property from the object, the service works; however, if I include the resolve property, I get the Unknown Provider error originating from that property.
The documentation for the resolve property reads:
(Type: Object) - Members that will be resolved and passed to the
controller as locals; it is equivalent of the resolve property in the
router.
The objective is to be able to provide a template for the modal that utilizes these properties in its DOM, e.g. :
<div ng-controller="CustomModalController">
<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body">
{{message}}
</div>
<div class="modal-footer">
<button class="ad-button ad-blue" type="button" ng-click="confirmAction()"></button>
<button class="ad-button ad-blue" type="button" ng-click="cancelAction()"></button>
</div>
</div>
What am I missing that is causing this error to be thrown?
You have two problems:
You need to define the controller in your modal config
Your resolve object needs to be a map of string: function, where string is the name of the dependency that will be injected into your modal's controller, and function is a factory function that will be used to provide that dependency when the controller is instantiated.
Working example: JSFiddle
JavaScript
angular.module('myApp', ['ui.bootstrap'])
.controller('MyModalController', MyModalController)
.directive('modalTrigger', modalTriggerDirective)
.factory('$myModal', myModalFactory)
;
function MyModalController($uibModalInstance, items) {
var vm = this;
vm.content = items;
vm.confirm = $uibModalInstance.close;
vm.cancel = $uibModalInstance.dismiss;
};
function modalTriggerDirective($myModal) {
function postLink(scope, iElement, iAttrs) {
function onClick() {
var size = scope.$eval(iAttrs.size) || 'lg'; // default to large size
var title = scope.$eval(iAttrs.title) || 'Default Title';
var message = scope.$eval(iAttrs.message) || 'Default Message';
$myModal.open(size, title, message);
}
iElement.on('click', onClick);
scope.$on('$destroy', function() {
iElement.off('click', onClick);
});
}
return {
link: postLink
};
}
function myModalFactory($uibModal) {
var open = function (size, title, message) {
return $uibModal.open({
controller: 'MyModalController',
controllerAs: 'vm',
templateUrl : 'templates/CustomModal.html',
size: size,
resolve: {
items: function() {
return {
title: title,
message: message
};
}
}
});
};
return {
open: open
};
}
HTML
<script type="text/ng-template" id="templates/CustomModal.html">
<div class="modal-header">
<h3 class="modal-title">{{vm.content.title}}</h3>
</div>
<div class="modal-body">
{{vm.content.message}}
</div>
<div class="modal-footer">
<button class="ad-button ad-blue" type="button" ng-click="vm.confirm()">
confirm
</button>
<button class="ad-button ad-blue" type="button" ng-click="vm.cancel()">
cancel
</button>
</div>
</script>
<button modal-trigger size="'sm'" title="'Hello World!'" message="'This is a test'">
Click Me
</button>
I have a todo list in AngularJS that looks like this
.controller('TodoCtrl', function ($scope) {
$scope.todos = [
{text:'Ask smth on Stackoverflow', done:false},
{text: 'Resolve this', done:false}
];
$scope.getTotalTodos = function () {
return $scope.todos.length;
};
$scope.addTodo = function () {
$scope.todos.push({text:$scope.formTodoText, done:false});
$scope.formTodoText = '';
};
$scope.clearCompleted = function () {
$scope.todos = _.filter($scope.todos, function(todo){
return !todo.done;
});
};
})
And I would like to add a Todo (with a text, and a boolean 'done') from another controller that is launched when I click a button.
How can I do that ?
A big THANKS to who will help me
Typically services are used to pass information back and forth. Create a service and store your TODO list inside there. Inject that service into both controllers. Each controller can now act on the items in the list
I will append Scotts answer with some shorted Code.
Like he said, the best is to use a Service ;)
The Service:
.factory('todoService', function() {
var todolist = [];
return {
getTodoList: function() {
return todolist;
}
addTodo: function(todo) {
todolist.push(todo);
},
getTotalTodos: function() {
return todolist.length;
},
// some other
}
});
Now you can inject the service into any controller via
.controller('TodoCtrl', function ($scope, todoService)
and then you can call the functions of the service in the controller, e.g.
$scope.addTodo = function () {
todoService.addTodo({text:$scope.formTodoText, done:false});
$scope.formTodoText = '';
};
By using Angular Services:
I've made a simple demo.
Hope this helps.
(function() {
var app = angular.module("myApp", []);
// myService service.- This service contains an array, called «todos» wich contains data.
app.service("myService", function() {
return {
todos: [{
"text": "Ask smth on Stackoverflow",
"done": false
}, {
"text": "Resolve this",
"done": false
}]
};
});
// Add the dependecy in the controller.
app.controller("Controller", ["$scope", "myService",
function($scope, myService) {
$scope.title = "TODOS";
// This function returns the data stored in the service.
$scope.getTodos = function() {
return myService.todos;
}();
$scope.getTotalTodos = function() {
return myService.todos.length;
};
// This functions contains the object with the values from the form.
$scope.addTodo = function(model) {
myService.todos.push({
text: model.text,
done: model.done
});
$scope.model.text = "";
};
}
]);
})();
<html data-ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>Demo</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body data-ng-controller="Controller">
<h3>{{title}}</h3>
<form id="myForm" ng-submit="addTodo(model)">
<label>
Todo
<input type="text" data-ng-model="model.text" />
</label>
<br />
<label>
Done
<input type="checkbox" data-ng-model="model.done" />
</label>
<br/>
<button type="submit">Add</button>
<hr />
<ul>
<li data-ng-repeat="todo in getTodos">
{{todo.text}} ({{todo.done}})
<input type="checkbox" data-ng-model="todo.done" />
</li>
</ul>
</form>
</body>
</html>
Update: Using the service in multiple controllers.
(function() {
var example = angular.module("starter", [])
example.service("todoService", function() {
return {
todos: [],
addTodo: function($text, $classe) {
this.todos.push({
text: $text,
done: false,
});
}
};
});
example.controller('nationsLeaguesCtrl', function($scope, todoService) {
$scope.randomNationsLeagues = function() {
var text = "Text 1";
todoService.addTodo(text, null);
};
})
example.controller('statsCtrl', function($scope, todoService) {
$scope.randomStats = function() {
var text = "Text 2";
todoService.addTodo(text, null);
};
})
example.controller('specialCtrl', function($scope, todoService) {
$scope.randomSpecial = function() {
var text = "Text 3";
todoService.addTodo(text, null);
};
})
example.controller('TodoCtrl', function($scope, todoService) {
$scope.getTodos = function() {
return todoService.todos;
}();
$scope.getTotalTodos = function() {
return todoService.todos.length;
};
$scope.clearCompleted = function() {
$scope.todos = _.filter($scope.todos, function(todo) {
return !todo.done;
})
};
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="starter">
<button class="button button-full button-light" ng-controller="nationsLeaguesCtrl" ng-click="randomNationsLeagues()">Nations & Leagues</button>
<button class="button button-full button-light" ng-controller="statsCtrl" ng-click="randomStats()">Stats</button>
<button class="button button-full button-light" ng-controller="specialCtrl" ng-click="randomSpecial()">Special</button>
<div ng-controller="TodoCtrl">
<ul>
<li ng-repeat="todo in getTodos">{{todo.text}}
<input type="checkbox" name="checkboxG1" id="checkboxG1" ng-model="todo.done" class="css-checkbox" />
<label for="checkboxG1" class="css-label" style="font-family:checkboxFont; color:#ffffff;"><span class="done-{{todo.done}}"></span>
</label>
</li>
</ul>
</div>
</body>