Dynamicaly adding external pages

by yoorek

HTML

<div ng-app="app" ng-controller="AppController">
    <button onclick="addPage()">Add Page</button>
    <pages>
        <page page="StaticPage"></page>
    </pages>
</div>

JavaScript

window.addPage = function () {
    var page = document.createElement('div');
    var parent = document.getElementsByTagName('pages')[0];

    page.setAttribute('page', 'AddedPage');
    page.setAttribute('ng-controller', 'PageController');
    page.innerHTML = '<input ng-model="data.name"> : {{data.name}}';

    parent.appendChild(page);

    var event = new CustomEvent(
        "pageLoaded", {
        detail: {
            page: "AddedPage",
            element: page
        },
        bubbles: true,
        cancelable: true
    });

    parent.dispatchEvent(event);
};

window.log = function (message) {
    var div = document.createElement('div');
    div.innerHTML = message;
    document.body.appendChild(div);
}

window.app = angular.module('app', []);

app.controller('AppController', function ($scope) {
    log('App Controller');

    $scope.data = {
        name: 'Data set in AppController'
    }
});

app.controller('PageController', function () {
    log('PageController of newly inserted element');
});

app.directive('page', function () {
    return {
        restrict: 'E',
        link: function (scope, element, attrs) {}
    }
});

app.directive('pages', function ($compile) {
    return {
        restrict: 'E',

        compile: function (tElement, tAttrs) {

            return function (scope, element, attrs) {
                element.on('pageLoaded', function (event) {
                    var page = angular.element(event.detail.element);
                    var linkFn = $compile(page);
                    var newScope = scope.$new();

                    newScope.data = {
                        name: 'DATA SET IN DIRECTIVE'
                    };

                    scope.$apply(function () {
                        linkFn(newScope);
                    });
                });
            }
        }
    }
});