DerM
DerM

Reputation: 1526

Angular dialog directive with compile function and ng-show does not work

Inspired from this article I created a dialog directive. But I want to be a bit more flexible (e.g. not creating new variables/functions in the controller by hand for each dialog. I also want to have no scope in the dialog because then other angular components in the dialog don't work as they would if they wouldn't be in the dialog.

So I thought of this:

angular.module('directives.dialog', [])
.directive('modalDialog', function() {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    compile: function(element, attrs) {
       var html = "<div class='ng-modal' ng-show='" + attrs.dialogid + "'><div class='ng-modal-overlay' ng-click='hideModal" + attrs.dialogid + "()'></div><div class='ng-modal-dialog' ng-style='dialogStyle'> <div class='ng-modal-close' ng-click='hideModal" + attrs.dialogid + "()'>X</div><div class='ng-modal-dialog-content' ng-transclude></div></div></div>"
       var newElem = $(html);
       element.replaceWith(newElem);

       return function(scope, element, attrs) {
          //link function
          scope[attrs.dialogid] = false; //don't show in the beginning
          scope['hideModal'+attrs.dialogid] = function() {
            scope[attrs.dialogid] = false;
          };
      }
    }
};
});

Usage would be like this:

<button ng-click="toggleModal('myDialog')">Play weather god</button>
<modal-dialog dialogId='myDialog'>
      <p>Some dialog content<p>
      Other components..
      <div ng-bind="tempValue"></div>
</modal-dialog>

The toggleModal is pretty simple in my controller:

$scope.toggleModal = function(id) {
        $scope[id] = !$scope[id];
};

My problem is that the ng-show has no effect, even though the dialogId gets set in the scope by the link function (also the toggling works, but as I said it has no effect). Also the dynamically generated hide function is in the scope.

I have the feeling that there is something general wrong with this approach. Can you give hints where the error might be or how to do it better?

Upvotes: 1

Views: 954

Answers (1)

bengro
bengro

Reputation: 1014

You need to compile the html markup, in order for the angular directives to come to life.

In code:

You need to first inject the $compile service:

.directive('modalDialog', function($compile) {...});

You can then use it, to compile the markup like this:

var html = "<div ... ng-show='" + attrs.dialogid + "'> ..."
var newScope = scope.$new();
var newElem = $compile(html)(newScope);
element.replaceWith(newElem);

You can pass any variables to the compiled markup using the newScope property. E.g.

var newScope = scope.$new();
newScope.prop1 = 'test';

Which can be accessed inside the template by using "prop1".

Upvotes: 1

Related Questions