Lean Controller - correct way

A lean controller that lets the model do all the work.

by Steven Lambert

HTML

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://code.angularjs.org/1.2.18/angular.min.js"></script>
<div ng-controller="myCtrl">
    <button ng-click="removeItem()">Remove first item</button>
    <ul>
        <li ng-repeat="item in model.items" ng-click="selectItem($index)" ng-class="{'selected': isSelected($index)}">{{item}}</li>
    </ul>
</div>
<div ng-controller="otherCtrl">{{getSelectedItem()}}</div>

CSS

.selected {
    color: red;
}

JavaScript

/**
 * 1. Model/data in a service
 * 2. Model/data manipulation in a service
 * 3. Logic in a service
 */
angular.module('myApp', []);

angular.module('myApp')
    .factory('myModel', function () {
    /* [1] */
    var model = {};

    model.items = ['one', 'two', 'three', 'four'];
    model.selectedItem = -1;

    /* [2] */
    model.removeItem = function removeItem(index) {
        if (index >= 0 && index < model.items.length) {
            model.items.splice(index, 1);
        }
    };

    /* [3] */
    model.isSelected = function isSelected(index) {
        return index === model.selectedItem;
    }

    return model;
});

angular.module('myApp')
    .controller('myCtrl', function ($scope, myModel) {

    $scope.model = myModel;

    $scope.removeItem = function () {
        myModel.removeItem(0);
    };

    $scope.selectItem = function (index) {
        myModel.selectedItem = index;
    }

    $scope.isSelected = function (index) {
        return myModel.isSelected(index);
    }
});

angular.module('myApp')
    .controller('otherCtrl', function ($scope, myModel) {
    $scope.getSelectedItem = function getSelectedItem() {
        return myModel.selectedItem;
    }
});