Evanion
Evanion

Reputation: 188

combine template with controller

I'm trying to make a service that will take a template and a controller, combine the two, and then send them to the frontend framework for injection to the DOM. The service would allow me to inject a modal at any time in the application.

The actual injection of the modal is already handled by uikit (bootstrap like framework). so the problem is only how to bind a controller/scope to a view-partial template. It would look something like this:

angular.module('user', ['modal'])
.controller('userCtrl', userCtrl)
.controller('userModalCtrl', userModalCtrl);

function userCtrl(modal){
  var uc = this;
  var modalConf = {
    templateUrl: 'components/user/tmpl/profilemodal.tpl.html',
    controller: 'userModalCtrl',
    controllerAs: 'um'
  }
  uc.openModal = modal.confirm(modalConf);
}

function userModalCtrl(){
  var um = this;
  um.user = {
    name: 'John doe',
    email: '[email protected]'
  }
}

Usually I would use a directive, but in this case, I don't want to add any markup to the application view beforehand. If I could call a directive programmatically, perhaps that would solve the issue.

I have been able to call the template, and have it injected in the DOM, correctly .. the question is... how do I bind a controller to it?

angular.module('modal', [])
.factory('modal', modalSrv);

function modalSrv($templateRequest, ukModal){
  var service = {};
  service.confirm = function (content, callback) {
    $templateRequest(content).then(function(data){
      new ukModal.confirm(data, callback);
    });
  };
  return service;
}

This service will correctly collect the HTML template referenced in content, and then send it to ukModal (.confirm specifies a type of modal), that in turn injects it in the DOM. the question is .. how do I bind a controller/scope to this template, before sending it off to ukModal?

Upvotes: 1

Views: 109

Answers (1)

Estus Flask
Estus Flask

Reputation: 222493

You don't need to do directive's job, even if there would be other Angular-compliant ways to do that.

app.directive('modal', function () {
  return {
    templateUrl: 'components/user/tmpl/profilemodal.tpl.html',
    controller: 'userModalCtrl',
    controllerAs: 'um'
  };
});

and

var modalElement = $compile('<modal>')($scope);
var modal = new ukModal.confirm(modalElement , callback);

The most obvious problem here is that $scope should be actual parent's scope. If it is not, make sure that the directive doesn't depend on it in any way, you can even pass empty object instead of $scope.

The less obvious problem is memory leaks. Watch for them. Non-ng code in conjunction with detached nodes is leakage-prone.

Upvotes: 1

Related Questions