Can I use the $ compilation in the Angular service directly on templateUrl instead of raw HTML or raw angular. Element?

Given the following service, designed to create an element of the "dialogue" (that is, 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 used in the controller as follows:

 $scope.someFunction = function() { dialog.createDialog(); }; 

Is there a way I can use $compile or something else to not have HTML in my service? I would rather just call the directive, so running createDialog() immediately introduces the directive into my DOM, and therefore the directive is responsible for combining the new controller and template together. If I am mistaken, I am fully prepared for constructive ideas.

+5
source share
2 answers

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 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 need to insert modal somewhere in the DOM, so $ document is entered.
  • Yes, you can take modal markup from here.
  • Remember to create new areas for the dialog and destroy them ($ rootScope. $ New).
  • This is WIP, I hope it is clear enough.
+9
source

You can try this as shown below, just to render your ng-include before opening a 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 below:

 dialog.compileInclude($scope, 'dialog.html').then(function(){ // open dialog here }); 
+1
source

Source: https://habr.com/ru/post/1203653/


All Articles