Building Pluggable Components in AngularJS: After

by codef0rmer

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.min.js"></script>
<div ng-controller="OneCtrl">
    <div pc-home></div>
    <div pc-profile></div>
</div>
<div class='header'>My Application</div>

<script type="text/ng-template" id="home.tpl.html">
    <div class='home-template' ng-show="stateService.openPanel == 'home'">
        <ul>
            <li ng-repeat="choice in choices" ng-bind-template="{{$index + 1}}. {{choice}}"></li>
        </ul>
    </div>
</script>
<script type="text/ng-template" id="profile.tpl.html">
    <div class='profile-template' ng-show="stateService.openPanel == 'profile'">
        <ul>
            <li ng-repeat="choice in choices" ng-bind-template="{{$index + 1}}. {{choice}}"></li>
        </ul>
    </div>
</script>

CSS

div[ng-controller="OneCtrl"] {
    background: gray;
    width: 100px;
    height: 100%;
    position: absolute;
    left: 0px;
    bottom: 0px;
}
.header {
    position: absolute;
    left: 100px;
    top: 0px;
    right: 0px;
    height: 50px;
    background: pink;
    text-align: center;
    line-height: 50px;
    font-size: 20px;
}
.home {
    width: 80px;
    margin: 10px 0 0 10px;
}
.profile {
    width: 80px;
    margin: 10px 0 0 10px;
}
.home-template, .profile-template {
    position: absolute;
    background: rgb(40, 96, 117);
    left: 100px;
    top: 50px;
    bottom: 0px;
    right: 0px;
    padding: 20px;
    overflow: auto;
    color: white;
}
.profile-template { background: rgb(150, 164, 170); color: rgb(44, 43, 40);  }

JavaScript

var App = angular.module('App', ['App.tools']);
angular.module('App.tools', ['tools.home', 'tools.profile']);

App.controller('OneCtrl', function($scope, StateService) {
    StateService.openPanel = 'home';
});

App.factory('StateService', function() {
    return {
        openPanel: ''
    };
});

// Separate module per feature
angular.module('tools.home', []).directive('pcHome', function($compile, StateService) {
    return {
        restrict: 'A',
        replace: true,
        scope: {},
        controller: function($scope, $element, $attrs) {
            $scope.stateService = StateService;
            
            $scope.toggle = function() {
                if (StateService.openPanel === 'home') {
                    StateService.openPanel = '';
                } else {
                    StateService.openPanel = 'home';                
                }
            };
            
            $scope.choices = [
               'Share whats new...',
               'You may know',
               'Updates from followers',
               'Few posts from communities',
               'Scrolling now for more updates',
               'Loading... :-)'
           ];
        },
        template: '<button class="btn home" ng-click="toggle()" ng-class="{true: \'btn-primary\', false: \'btn-success\'}[stateService.openPanel == \'home\']">Home</button>',
        link: function(scope, element, attrs) {
            angular.element(document.getElementsByTagName('body')).append(
                $compile('<div ng-include="\'home.tpl.html\'"></div>')(scope)
            );
        }
    };
});

angular.module('tools.profile', []).directive('pcProfile', function($compile, StateService) {
    return {
        restrict: 'A',
        replace: true,
        scope: {},
        controller: function($scope, $element, $attrs) {
            $scope.stateService = StateService;
            $scope.toggle = function() {
                if (StateService.openPanel === 'profile') {
             ...