Dynamically add directives in AngularJS

For a walkthrough see http://blog.fourtonfish.com/post/74055065673/dynamically-add-directives-in-angularjs-no-jquery

by dbouwman

HTML

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<section ng-app="myApp" ng-controller="MainCtrl">
    <h1>Dynamically Add Directives</h1>
    <p>{{greeting}}</p>
    <p>Count: {{count}}</p>
        
        <ul >
        <li ng-repeat="item in header.blocks">
            {{item.name}} + {{ item.type }}
        </li>
    </ul>
    
        <input type="text" ng-model="greeting">
    
    <addbuttonsbutton x-greeting="greeting" x-items="items" x-header="header" x-count="count"></addbuttonsbutton>
    <div id="space-for-buttons"></section>


    {{items | json}}
</section>

CSS

section{
    padding: 2em;   
}
button{
    padding:0.3em;
    margin: 0.3em;
}

JavaScript

var myApp = angular.module('myApp', []);

function MainCtrl($scope) {
	$scope.count = 0;
    $scope.greeting = 'Hello';
    $scope.header = {
        blocks:[
            {name:'block 1', type:'text'},
            {name:'block 2', type:'image'},
        ]
    };
    $scope.items = [{name:'blarg'}];
}

//Directive that returns an element which adds buttons on click which show an alert on click
myApp.directive("addbuttonsbutton", function($compile){
	return {
        scope: {
            header:'=header',
            items: '=items',
            count: '=',
            greeting:'='
        },
		restrict: "E",
		template: "<button >Click to add buttons</button>",
        link: function(scope, element, attrs){
            console.log('Scope.items: ' + scope.items);
		    element.bind("click", function(){
                

                
                var d = $compile("<div><button class='btn btn-default' x-greeting=\"greeting\" x-header=\"header\" data-alert="+scope.count+">Show alert #"+scope.count+ "  {{ greeting }} </button></div>")(scope);
                angular.element(document.getElementById('space-for-buttons')).append(d);
                
                scope.$apply(function(){
                    scope.count++;
                    scope.header.blocks.push({name:'someName' + scope.count});
                });
                
            });
        }
	}
});


//Directive for showing an alert on click
myApp.directive("alert", function(){
    return {
        scope: {
            header:'=',
            greeting: '='
        },
        link: function(scope, element, attrs){
            element.bind("click", function(){
                console.log(scope);
                alert("This is alert #"+attrs.alert + ' name: ' + scope.header.blocks[attrs.alert].name + ' ' + scope.greeting);
            });
        }
	};
});