Given the following service that is meant to create a "dialog" element (i.e. a modal):
app.service('dialog', ['$document', '$compile', '$rootScope',
    function($document, $compile, $rootScope) {
        var body = $document.find('body');
        var scope = $rootScope.$new();
        this.createDialog = function() {
            var dialogElem = angular.element('<div ng-include="\'/dialog.html\'"></div>');
            $compile(dialogElem)(scope);
            body.append(dialogElem);
        };
    }
]);
which can be utilized in a controller like so:
$scope.someFunction = function() {
    dialog.createDialog();
};
Is there a way that I can use $compile or anything else to not have HTML in my service? I'd really prefer to just invoke a directive, so that running createDialog() immediately injects a directive into my DOM and thus the directive is responsible for linking a new controller and template together. If I'm going about this the wrong way I'm totally open to constructive ideas.
Overview. Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together. The compilation is a process of walking the DOM tree and matching DOM elements to directives.
replace: true means that the content of the directive template will replace the element that the directive is declared on, in this case the <div myd1> tag.
templateUrl can also be a function which returns the URL of an HTML template to be loaded and used for the directive. AngularJS will call the templateUrl function with two parameters: the element that the directive was called on, and an attr object associated with that element.
Answer:The link option is just a shortcut to setting up a post-link function. controller: The directive controller can be passed to another directive linking/compiling phase. It can be injected into other directices as a mean to use in inter-directive communication.
Of course you can!, here you go:
app.factory('modalService', function ($document, $compile, $rootScope, $templateCache, $http) {
    var body   = $document.find('body'),
        modals = [];
    var service = {
        show: function (template, data, modal) {
            // The template's url
            var url = 'template/modal/' + template + '.html';
            // A new scope for the modal using the passed data
            var scope = $rootScope.$new();
            angular.extend(scope, data);
            // Wrapping the template with some extra markup
            modal = modal || angular.element('<div class="modal"/>');
            // The modal api
            var api = {
                close: function () {
                    modal.remove();
                    scope.$destroy();
                    modals.splice(modals.indexOf(api), 1);
                },
                replace: function (template, data) {
                    return angular.extend(api, service.show(template, data, modal));
                }
            };
            // Adding the modal to the body
            body.append(modal);
            // A close method
            scope.close = api.close;
            // Caching the template for future calls
            $http.get(url, {cache: $templateCache})
                .then(function (response) {
                    // Wrapping the template with some extra markup
                    modal.html('<div class="win">' + response.data + '</div>');
                    // The important part
                    $compile(modal)(scope);
                });
            modals.push(modal);
            return api;
        },
        showOrReplaceLast: function (template, data) {
            return service.show(template, data, modals.length > 0 ? modals[modals.length - 1] : null);
        }
    };
    return service;
});
Some notes:
You could try this as below, just to render your ng-include before opening the dialog
app.service('dialog', ['$http', '$compile', '$q', '$templateCache'
    function($http, $compile, $q, $templateCache) {
        this.compileInclude = function(scope, url) {
            var deferred = $q.defer();
            $http.get(url, {cache : $templateCache}).then(function(response){
                deferred.resolve($compile(response.data)(scope));
            });
            return deferred.promise;
        };
    }
]);
From the controller write as below
dialog.compileInclude($scope, 'dialog.html').then(function(){
    // open dialog here
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With