| Year | Device | Processor | Ram | 
| 2007 | iPhone 1 | 620 MHz | 128 MB | 
| Year | Device | Processor | Ram | 
| 2007 | iPhone 1 | 620 MHz | 128 MB | 
| 2010 | iPhone 4 | 1 GHz                      | 
			512 MB | 
| Year | Device | Processor | Ram | 
| 2007 | iPhone 1 | 620 MHz | 128 MB | 
| 2010 | iPhone 4 | 1 GHz | 512 MB | 
| 2014 | iPhone 6 | 1.4 GHz dual-core | 1 GB | 
| Year | Device | Processor | Ram | 
| 2007 | iPhone 1 | 620 MHz | 128 MB | 
| 2010 | iPhone 4 | 1 GHz | 512 MB | 
| 2014 | iPhone 6 | 1.4 GHz dual-core | 1 GB | 
| 2015 | iPhone 6s | 1.8 GHz dual-core | 2 GB | 
(You'll feel right at home)
Extends the HTML vocabulary
Proven for large-scale app development
UI Components using Directives & Services
CSS generated from the Sass preprocessor
Quickly give your app its own look and feel
CSS designed to be easily overridden
iOS 6+
Android 4+
Win Phone 10
    angular.module(
        'todo', 
        [
          'ionic',
          'todo.services',
          'backand',
          'todo.backand',
          'todo.config.constants',
          'todo.interceptors'
        ]
    );
    www\js\app.js
    angular.module(
        'todo', 
        [
          'ionic',
          'todo.services',
          'backand',
          'todo.backand',
          'todo.config.constants',
          'todo.interceptors'
        ]
    );
    <body ng-app="todo">
    www\js\app.js & www\index.html
     angular
       .module('todo')
       .config(config);
     config.$inject = ['BackandProvider', '$stateProvider', 
            '$urlRouterProvider', '$httpProvider', 'CONSTS'];
     function config(
         BackandProvider, 
         $stateProvider, 
         $urlRouterProvider, 
         $httpProvider, 
         CONSTS) {
            BackandProvider.setSignUpToken(CONSTS.signUpToken);
            BackandProvider.setAppName(CONSTS.appName);
            $httpProvider.interceptors.push('APIInterceptor');
     })www\js\config\app.config.js
$stateProvider
  .state('login', {
    url: '/login',
    templateUrl: 'templates/login.html',
    controller: 'LoginController as login'
  })
    www\js\config\app.config.js
.state('tab', {
  url: '/tab',
  abstract: true,
  templateUrl: 'templates/tabs.html'
})
    www\js\config\app.config.js
.state('tab.projects', {
  url: '/projects',
  views: {
     'tab-projects': {
      templateUrl: 'templates/tab-projects.html',
      controller: 'ProjectsController as vm'
    }
  }
})
    www\js\config\app.config.js
.state('tab', {
  url: '/tab',
  abstract: true,
  templateUrl: 'templates/tabs.html'
})
    <ion-tab 
    title="Projects" 
    icon="ion-document" 
    href="#/tab/projects">
    <ion-nav-view 
        name="tab-projects">
    </ion-nav-view>
</ion-tab>
    www\js\config\app.config.js
.state('tab.projects', {
  url: '/projects',
  views: {
     'tab-projects': {
      templateUrl: 'templates/tab-projects.html',
      controller: 'ProjectsController as vm'
    }}
})
    <ion-tab 
    title="Projects" 
    icon="ion-document" 
    href="#/tab/projects">
    <ion-nav-view 
        name="tab-projects">
    </ion-nav-view>
</ion-tab>
    www\js\config\app.config.js
.state('tab.projects', {
  url: '/projects',
  views: {
     'tab-projects': {
      templateUrl: 'templates/tab-projects.html',
      controller: 'ProjectsController as vm'
    }}
})
    www\js\config\app.config.js
    $urlRouterProvider.otherwise('/projects');
    
    $urlRouterProvider.otherwise('/projects');
    $urlRouterProvider.otherwise(function ($injector) {
    
        var $state = $injector.get("$state");
        $state.go("tab.projects");
    });
    www\js\config\app.config.js
<ion-view view-title="Projects">
    <ion-content>
        <!-- Content Here -->
    </ion-content>
</ion-view>
    www\templates\tab-projects.html
    <ion-list>
      <ion-item class="item item-text-wrap" 
            ng-repeat="project in vm.projects | orderBy:'name'" 
            ui-sref="tab.tasks({
                  projectId: project.id,
                  projectName: project.name
              })">
            <h2>{{project.name}} </h2>
            <p>created: {{project.created_on}}</p>
             <ion-option-button 
                class="button-assertive "
                ng-click="vm.deleteProject(project) ">
                  Delete
            </ion-option-button>
      </ion-item>
    </ion-list>
    www\templates\tab-projects.html
    (function () {
      'use strict';
      angular
        .module('todo')
        .controller('ProjectsController', ProjectsController);
      ProjectsController.$inject = [
            'ProjectService', '$ionicModal', 
            '$state', '$scope', 
            '$ionicListDelegate', 'projects'];
      function ProjectsController(ProjectService, $ionicModal, 
            $state, $scope, 
            $ionicListDelegate, projects) {
        }
    })();
    www\js\controllers\projects.controller.js
    function getMoreProjects() {
        ...
        $scope.$broadcast('scroll.infiniteScrollComplete')
    }
    function doRefresh() {
        ...
        $scope.$broadcast('scroll.refreshComplete');
    }
    www\js\controllers\projects.controller.js
| constant | store values that will never change | 
(function () {
  angular.module('todo.config.constants', [])
    .constant('CONSTS', {
      anonymousToken: 'ec9b4565-8d2e-4740-a4dc-4e8e52dbbc72',
      signUpToken: '536d7143-edf0-451b-9e8d-fa065c563eb6',
      appName: 'ddjtodo'
    })
    .constant('$ionicLoadingConfig', {
      template: '<ion-spinner></ion-spinner>'
    })
})();www\js\config\app.constants.js
| constant | store values that will never change | 
| factory | Service created using constructor function Uses Revealing Module pattern  | 
                
        angular
            .module('todo.services')
            .factory('ProjectService', ProjectService);
        ProjectService.$inject = [];
        function ProjectService() {
           var service = {
           };
        
           return service;
           
        }www\js\services\projects.service.js
    angular.module('todo.services')
        .factory('ProjectService', ProjectService);
    ProjectService.$inject = [
        '$http', 'BackandDataService', 'UserModel'
    ];
    function ProjectService($http, BackandDataService, UserModel) {
        var service = {
          getProjects: getProjects,
          addProject: addProject,
          deleteProject: deleteProject,
        };
        return service;
        function getProjects(pageNumber, pageSize) {}
        function addProject(name) {}
        function deleteProject(project) {}
    }
www\js\services\projects.service.js
| constant | store values that will never change | 
| service | Service created using constructor function. using the this keyword and more OOP-like  | 
                
| factory | Service created using constructor function Uses Revealing Module pattern  | 
                
(service)
      angular.module('todo.interceptors')
        .service('APIInterceptor', ApiInterceptor);
      ApiInterceptor.$inject = ['$rootScope', '$q'];
      function ApiInterceptor($rootScope, $q) {
        var service = this;
        service.responseError = responseError;
        service.request = request;
        service.response = response;
    
        function request(config) { return config }    
        function response(response) { return response; }
        function responseError(response) { 
            return $q.reject(response); 
        }
    }www\js\interceptors\api.interceptor.js
    function request(config) {
        $rootScope.$broadcast('loading:show');
        return config;
    }
    
    function response(response) {
        $rootScope.$broadcast('loading:hide');
        return response;
    }
    function responseError(response) {
        $rootScope.$broadcast('loading:hide');
        return $q.reject(response);
    }
    www\js\interceptors\api.interceptor.js
    angular
      .module('todo')
      .config(config);
    config.$inject = [
        'BackandProvider', '$stateProvider', 
        '$urlRouterProvider', '$httpProvider', 'CONSTS'];
    function config(
        BackandProvider, $stateProvider, 
        $urlRouterProvider, $httpProvider, CONSTS) {
        $httpProvider.interceptors.push('APIInterceptor');
    }www\js\config\app.config.js
Text
return $http ({
  method: 'GET',
  url: Backand.getApiUrl() + '/1/objects/project',
  params: {
    pageSize: 20,
    pageNumber: 1,
    filter: null,
    sort: ''
  }
});
    
    Backand.signin(email, password);
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    Backand.signout();
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    Backand.signout();
    Backand.socialSignIn(provider);
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    Backand.signout();
    Backand.socialSignIn(provider);
    Backand.socialSignUp(provider);
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    Backand.signout();
    Backand.socialSignIn(provider);
    Backand.socialSignUp(provider);
    Backand.getUserDetails()
    www\js\services\login.service.js
    Backand.signin(email, password);
    Backand.signup(
        firstName, lastName, 
        email, password, confirmPassword);
    Backand.signout();
    Backand.socialSignIn(provider);
    Backand.socialSignUp(provider);
    Backand.getUserDetails()
    Backand.getToken()
    www\js\services\login.service.js
$ ionic serve
    
<ion-item 
          class="item item-text-wrap" 
          ng-repeat="project in vm.projects | orderBy:'name'" 
          ui-sref="tab.tasks({ 
            projectId: project.id, projectName: project.name })" 
          ng-style="{'line-height': '50px'}"
        >
        <h2>{{project.name}} </h2>
  18        <i class="ion-chevron-right icon"></i>
        <p>created: {{project.created_on}}</p>
        <ion-option-button class="button-assertive "
                       ng-click="vm.deleteProject(project) ">
            Delete
        </ion-option-button>
</ion-item>www\templates\tab-projects.html
<ion-item 
  11      class="item item-text-wrap item-icon-right" 
          ng-repeat="project in vm.projects | orderBy:'name'" 
          ui-sref="tab.tasks({ 
                projectId: project.id, projectName: project.name })" 
          ng-style="{'line-height': '50px'}"
        >
        <h2>{{project.name}} </h2>
        <i class="ion-chevron-right icon"></i>
        <p>created: {{project.created_on}}</p>
        <ion-option-button class="button-assertive "
                       ng-click="vm.deleteProject(project) ">
            Delete
        </ion-option-button>
</ion-item>www\templates\tab-projects.html
<ion-item 
          class="item item-text-wrap item-icon-right" 
          ng-repeat="project in vm.projects | orderBy:'name'" 
          ui-sref="tab.tasks({ 
                projectId: project.id, 
                projectName: project.name })" 
          ng-style="{'line-height': '50px'}"
        >
        <h2>{{project.name}} </h2>
  18    <i class="ion-chevron-right icon icon-accessory"></i>
        <p>created: {{project.created_on}}</p>
        <ion-option-button class="button-assertive "
                       ng-click="vm.deleteProject(project) ">
            Delete
        </ion-option-button>
</ion-item>www\templates\tab-projects.html
<ion-view enable-menu-with-back-views="true">
    <ion-nav-title>Tasks: {{vm.project.name}}
    </ion-nav-title>
  4    <ion-nav-buttons side="right">
            <button 
                    class="button button-icon ion-compose" 
                    ng-click="vm.showTaskModal()">       
            </button>
        </ion-nav-buttons>
    <ion-content>
    ...
    <ion-content>
</ion-view>www\templates\tab-project-tasks.html
  34  function activate() {    
    
        $ionicModal
            .fromTemplateUrl('templates/modal-new-task.html', {
                scope: $scope
            }).then(function(modal) {
                vm.taskModal = modal;
            });
      }
www\js\controllers\tasks.controller.js
  96    function showTaskModal() {
            vm.taskModal.show();
        }
 
        function closeTaskModal() {
            vm.taskModal.hide();
        }
        $scope.$on('$destroy', function () {
          vm.taskModal.remove();
        });www\js\controllers\tasks.controller.js
  82
    function saveNewTask(task) {
      TaskService.addTask(vm.project, task)
        .then(function (result) {
        
              vm.tasks.push(result);
              closeTaskModal();
      
              task.name = '';
      });
    }www\js\controllers\tasks.controller.js
  12
<ion-item 
    class="item-text-wrap item item-icon-right" 
    ng-repeat="task in vm.tasks | orderBy: ['completed','name']">
        {{task.name}}
         
        <i class="ion-close icon icon-accessory"
            ng-click="vm.deleteTask(task)"></i>
      </ion-item>www\templates\tab-project-tasks.html
  100
     function deleteTask(task) {
        TaskService.deleteTask(vm.project, task)
            .then(function (result) {  
        
              vm.tasks.splice(vm.tasks.indexOf(task), 1);
         });
    }www\js\controllers\tasks.controller.js
  12
<ion-item 
    class="item-text-wrap item  item-icon-left item-icon-right" 
    ng-repeat="task in vm.tasks | orderBy: ['completed','name']">
        {{task.name}}
        <i class="icon"
            ng-class="task.completed ? 
                'ion-checkmark-circled' : 'ion-ios-circle-outline'"
            ng-click="vm.completeTask(task, $index)">
        </i>
        <i class="ion-close icon icon-accessory"
            ng-click="vm.deleteTask()"></i>
</ion-item>www\templates\tab-project-tasks.html
  96
     function completeTask(task) {
        TaskService.completeTask(vm.project, task)
            .then(function (result) {
        });
    }www\js\controllers\tasks.controller.js
  10
  <ion-content>
    <ion-refresher
        pulling-text="Pull to refresh..."
        on-refresh="vm.doRefresh()">
    </ion-refresher>
    <ion-list ng-if="vm.tasks.length > 0">
www\templates\tab-project-tasks.html
  62
    function doRefresh() {
        vm.refreshing = true;
        vm.pageNumber = 1;
        TaskService.getTasks(vm.project, vm.pageNumber, vm.pageSize)
            .then(function (result) {          
              vm.tasks = result;
        })
        .finally(function () {
            $scope.$broadcast('scroll.refreshComplete');
            vm.refreshing = false;
        });
    }
www\js\controllers\tasks.controller.js
  21
<ion-infinite-scroll 
        on-infinite="vm.getMoreTasks() "
        ng-if="vm.moreDataCanBeLoaded 
                && !vm.refreshing 
                && vm.tasks.length > 0" 
        immediate-check="false" 
>
</ion-infinite-scroll>www\templates\tab-project-tasks.html
  43
    function getMoreTasks() {
      vm.pageNumber = vm.pageNumber + 1;
      TaskService.getTasks(vm.project, vm.pageNumber, vm.pageSize)
        .then(function (result) {
          var rowNum = result.length;
          if (rowNum === 0 || rowNum < vm.pageSize) {
            vm.moreDataCanBeLoaded = false;
          }
          if (rowNum > 0) {
            vm.tasks = vm.tasks.concat(result);
          }
        })
        .finally(function () {
          $scope.$broadcast('scroll.infiniteScrollComplete')
        });
    }
www\js\controllers\tasks.controller.js
  10
    <ion-tab title="Profile" 
        icon="ion-ios-person" 
        href="#/tab/profile">
        
            <ion-nav-view name="tab-profile"></ion-nav-view>
    </ion-tab>www\templates\tabs.html
  66
  .state('tab.profile', {
      url: '/profile',
      views: {
        'tab-profile': {
          templateUrl: 'templates/tab-profile.html',
          controller: 'ProfileController as vm',
        }
      }
    })www\js\config\app.config.js
  103
    TasksController.$inject = ['TaskService', '$stateParams', 
        '$ionicModal', '$scope', 'tasks', 
        '$ionicPopup'];
    function TasksController(TaskService, $stateParams, 
        $ionicModal, $scope, tasks, 
        $ionicPopup) {
        ....
        function deleteTask(task) {
            $ionicPopup.confirm({
                title: 'Are You Sure?',
                template: 'Are you sure you want to delete this task?'
            }).then(function (res) {
                if (res) {
                    TaskService.deleteTask(vm.project, task)
                        .then(function (result) {                     
                        vm.tasks.splice(vm.tasks.indexOf(task), 1);
                    });
                }
            });
        }www\js\tasks.controller.js
/*
$light:                           #fff !default;
$stable:                          #f8f8f8 !default;
$positive:                        #387ef5 !default;
$calm:                            #11c1f3 !default;
$balanced:                        #33cd5f !default;
$energized:                       #ffc900 !default;
$assertive:                       #ef473a !default;
$royal:                           #886aea !default;
$dark:                            #444 !default;
*/
scss\ionic.app.scss
$calm: pink !default;
  15
<ion-item 
    class="item-text-wrap item item-icon-left  item-icon-right" 
    ng-repeat="task in vm.tasks | orderBy: ['completed','name']"
        
    ng-class="{completedTask: task.completed}"
>
    {{task.name}}
    <i class="icon"
        ng-class="task.completed ? 
            'ion-checkmark-circled' : 'ion-ios-circle-outline'"
          ng-click="completeTask(task, $index)">
    </i>
    <i class="ion-close icon icon-accessory"
        ng-click="vm.deleteTask()"></i>
</ion-item>www\templates\tab-project-tasks.html
  50
.completedTask {
	text-decoration: line-through;
	color: #A9A9A9;	
}scss\app.scss
Automatically generate icons and splash screens
Creates size needed for each platform
$ ionic resources
$ ionic resources --icon
$ ionic resources --splashWeb Site - ionicframework.com
	 
Docs - ionicframework.com/docs/
	 
Ionic Meetups - blog.ionic.io/ionic-worldwide
	 
Ionic Slack - ionicworldwide.herokuapp.com
	 
Ionic Forums - blog.ionic.io/ionic-worldwide