Bug in ng-show with custom directive and transclude?

30 views
Skip to first unread message

Charles Moore

unread,
Apr 22, 2015, 7:57:22 PM4/22/15
to ang...@googlegroups.com
So I'm trying to show a chunk of HTML as the contents of a modal dialog and I've constructed a custom directive for this purpose. The directive is mostly uninteresting but looks like this:

client.directive('modalDialog', function ()
{
   return {
      restrict: "E",
      replace: true,
      transclude: true,
      templateUrl: "templates/modalDlg.html",
      link: function (scope, element, attrs)
            {
            }
          }
})

The key important feature of the directive is that I'm using transclusion.

Now my modalDlg.html template looks like this:

<div>
   <div class='modal-background'></div>
   <div ng-transclude></div>
</div>

Again, not very interesting.

Where it gets interesting is with my use of the directive via HTML that looks like this:

<modal-dialog ng-show='showTheDialog'>
   Bunch of HTML appears here.
</modal-dialog>

Elsewhere, I have an clickable div that looks like this:

   <div ng-click='showTheDialog=true'>

This works just fine to show the dialog. When the div is clicked, the dialog pops up. But, here's the weird part. If I examine the scope while the dialog is up, showTheDialog has mysteriously been set back to false! So if I have a button (as I do) that tries to bring down the dialog by setting showTheDialog to false, it doesn't work, because Angular detects no change in the value of that scope variable.

But to really seal the deal of weirdness here, if I change the clickable div to be like this:

   <div ng-click='ShowTheDialogPlease()'>

where ShowTheDialogPlease is defined like this:

   $scope.ShowTheDialogPlease = function ()
      {
      $scope.showTheDialog = true
      }

Then everything works! As expected, while the dialog is up, showTheDialog is true and now, when I click on my take-down button, the dialog is dismissed as it should be.

This really looks a lot to me like an Angular bug. It's hard for me to see how 

   <div ng-click='showTheDialog=true'>

should behave so differently from 

   <div ng-click='ShowTheDialogPlease()'>

Has anybody encountered anything like this? Can you confirm or deny that this is an Angular bug?

Sander Elias

unread,
Apr 23, 2015, 3:16:27 AM4/23/15
to ang...@googlegroups.com

Hi Charles,

This is not a bug. Transclusion creates a new scope. Your <div ng-click='showTheDialog=true'> sets the showTheDialog value inside that scope, in stead of where you expect it. If you use a function, it will get called, and sets the the value in the scope where you would expect it.
To cut a long story short. Don’t use $scope, use controllerAs, and you will never have this kind of issue anymore.

Regards
Sander

Reply all
Reply to author
Forward
0 new messages