4

I created this plnkr when answering this question 'AngularJS - open controller in a dialog (template loaded dynamically)'.

All the example app does is launch a dialog box based on a template, with it's own controller. The first time the dialog launches, everything works as expected. However, if I try and re-launch the dialog, after dismissing it, the modal backdrop is shown but no dialog. In the javascript console you can see that the then method on the promise returned by $dialog.open() is called immediately, but the backdrop isn't removed and no errors are reported. I'm completely baffled.

The dialog can be opened and closed repeatedly on the angular-ui bootstrap documentation page.

Where did I go wrong?

HTML:

<!DOCTYPE html>
<html ng-app="plnkr">

  <head>
    <link data-require="bootstrap-css@*" data-semver="2.3.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" />
    <script data-require="angular.js@1.0.7" data-semver="1.0.7" src="http://code.angularjs.org/1.0.7/angular.min.js"></script>
    <script data-require="ui-bootstrap@0.3.0" data-semver="0.3.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.3.0.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-view></div>
  </body>

</html>

JS:

app.controller("DemoCtl", ["$scope", "$dialog", function($scope, $dialog){
  $scope.launch = function() {
    var d = $dialog.dialog({
      backdrop: true,
      keyboard: true,
      backdropClick: true,
      templateUrl: "dialog.html",
      controller: "DialogCtl"
    });

    d.open().then(function(result) { console.log("d.open().then"); });
  };
}]);
Community
  • 1
  • 1
Jason
  • 15,915
  • 3
  • 48
  • 72
  • I forked your plunker and updated it, but wasn't able to resolve the issue. http://plnkr.co/edit/E6KCrZZflP8zap3F180H It appears that once the _open is being set to false after being opened the first time, it never is getting reset to open – Mark Meyer Jun 05 '13 at 16:18
  • hopefully someone will be able to let us know what's going on. i agree that something isn't being set properly, but it sure isn't obvious. – Jason Jun 05 '13 at 16:23

3 Answers3

7

I've found the issue. It has to do with using an <a> tag to open the dialog. Clicking on the <a> tag causes a location change to be fired. The dialog handles location change by closing itself as you can see below.

  this.handleLocationChange = function() {
    self.close();
  };

I'm not sure why this doesn't happen on the first click of the <a> tag, but it definitely happens on all subsequent calls.

You can see in this plunker that if you use a button, it opens correctly each time.

Hope this helps! I'll try to figure out why it doesn't break on the first time.

EDIT

The location change is actually really bad. It appears to be looping, to what I believe is the angular maximum of 10 digests. Still not sure why it doesn't do a location change on the first click.

Mark Meyer
  • 3,643
  • 3
  • 23
  • 34
  • Good catch - you just saved my ocd-ness from messing with this for the next hour. – rGil Jun 05 '13 at 17:01
  • very strange, for some reason i thought ng-click prevented an anchor from firing the location change event. how come using an anchor to trigger ng-click breaks here, but not in other scenarios? because we're using routes? – Jason Jun 05 '13 at 18:23
  • I thought the same about ng-click. Like I said in my edit, it's not firing the locationStateChange multiple times. Might be some deeper but I haven't investigated further yet – Mark Meyer Jun 05 '13 at 18:43
  • 1
    I lost several hours to this issue - had to add each little piece of puzzle from local working version of Dialog example on http://angular-ui.github.io/bootstrap/ to my scenario. Eventually discovered having an href="#" in the anchor tag was causing it - href="" seems to work fine though. – Godders Jun 24 '13 at 11:22
  • @Jason getting "400 www.plnkr.co is currently stopped" – Ravish Sep 06 '13 at 06:52
0

It looks like if you put "javascript:;" in the href, then it works fine for the <a> tag.

Like this:

<a href="javascript:;" ng-click="launch()">Open the dialog</a>

Also, the <a> tag issue seems to be browser related.

0

The trouble is indeed with the tag. Jason mentioned that he expected that the angular directive would stop the location change. This is so, but it needs the href to be blank. the plunker was

<a href="javascript:;" ng-click="launch()">Open the dialog</a>

and should have been

<a href="" ng-click="launch()">Open the dialog</a>

When I changed the plunker to that effect everything seemed okay

SystemsGuy
  • 153
  • 10