0

I am working on a modal for a client. I have created a directive that works great, the problem is that one modal is made ahead each time it is used like..

What I have

<div ng-repeat="item in items">
  <a data-toggle="modal" data-target="{{item.id}}">Click</a>
  <my-dialog element-id="item.id">
    <h1>This is the body of the modal</h1>
  </my-dialog>
</div>

This works great for a small amount of modals but we are using a very large number of modals. So I would like to add the directive at runtime, something closer to...

What I want...

<div id="warning"></div>
<div ng-repeat="item in items">
  <a data-toggle="modal" data-target="{{item.id}}" ng-click="showModal(item)">Click</a>
</div>
...
// inside controller
$scope.showModal = function(item){
  $http.get('/someUrl').success(function(data){
    var result = $compile('<my-dialog element-id="'+item.id+'">'+data+'</my-dialog>').($scope);
    $("#warning").append(result);
  });
}
$scope.hideModal = function(){
  $( "#warning" ).empty();
}

This of course isn't working yet. Also it doesn't feel like the best way. This would allow me to remove the directive once it has been closed.

Please include a plunker or equivalent for the check.

3
  • Do you see any error in console? seems like a syntax error here $compile('<my-dialog element-id="'+item.id+'">'+data+'</my-dialog>')($scope); Commented Aug 11, 2014 at 21:04
  • Right that is part of the problem I have no idea where to get it from. Commented Aug 11, 2014 at 23:15
  • it must be data.data... do a console log of data and inject $ compile in your directive Commented Aug 11, 2014 at 23:17

2 Answers 2

1

One way you could do this is to use ng-repeat with your items, then call $scope.$apply() after you push a new item to the list. The HTML could look like this ...

<div ng-repeat="item in items">
  <span dialog>
    <a class="dialog-anchor">{{item.name}}</a>
    <div class="dialog-body">{{item.id}}</div>
  </span>
</div>

... and the directive like this

.directive('dialog', [function () {
    return {
    scope: {
    id: '@elementId',
  }
  , link: function (scope, el, attrs) {
    var body = $(el).find('.dialog-body').detach();
    $(el).find('.dialog-anchor').on('click', function () {
      $('body').append(body);
    });
  }};
  }])

... and the controller like this

.controller('app', ['$scope', function ($scope) {
  $scope.items = [
    {name: 'first', id: 001},
    {name: 'second', id: 002}
  ];

  setTimeout(function () {
    $scope.items.push({name: 'three', id: 003});
    if (!$scope.$$phase) $scope.$apply();
  }, 2000);  
}])

Here's the plunker... http://plnkr.co/edit/2ETbeCKGcHW3CJCfD9d7?p=preview. You can see the $scope.$apply call in the setTimeout where I push a new item to the array.

Sign up to request clarification or add additional context in comments.

Comments

0

Try this:

 var result = $compile('<my-dialog element-id="'+item.id+'">'+data+'</my-dialog>')($scope);

1 Comment

Where does compile come from? can you show me a plunker?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.