2

It works normally, but doesn't work after an ngClick.

  1. Why is this?
  2. How should this be dealt with if you do want it to work after an ngClick?

It actually works in the snippet below, but doesn't work in this Plunker, and also doesn't work in my app.

It also never works more than once in any of the three places, and I don't know why that is.

angular
  .module('app', ['ui.bootstrap'])
  .controller('MainController', MainController)
;

function MainController() {
  var vm = this;
  vm.updateSuccess = false;
  
  vm.closeUpdateSuccess = function() {
    console.log('closeUpdateSuccess');
    vm.updateSuccess = false;
  };
  
  vm.submit = function() {
    vm.updateSuccess = true;
  };
}
<!DOCTYPE html>
<html ng-app='app'>

  <head>
    <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
    <script data-require="angular.js@1.4.3" data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js"></script>
    <script data-require="ui-bootstrap@0.13.3" data-semver="0.13.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap.min.js"></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.4/ui-bootstrap-tpls.min.js'></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <div ng-controller='MainController as vm'>
      <alert ng-show='vm.updateSuccess' type='success' close='vm.closeUpdateSuccess()' dismiss-on-timeout='2000'>
        Successfully updated!
      </alert>
      
      <h1>Test Text</h1>
      
      <button ng-click='vm.submit()'>Submit</button>
    </div>
  </body>

</html>
Adam Zerner
  • 17,797
  • 15
  • 90
  • 156

2 Answers2

3

The problem is you are not using the alert directive correctly. It is working as designed and you can see this by looking at the console in your browser. When the page is rendered, two seconds later your logging statement is executed. The alert directive doesn't know or care whether or not it is visible. Angular will execute the directive when it is added to the DOM. For ng-show as you are using, it is only ever added once. You could use ng-if to achieve the desired behavior or, as I say below, ng-repeat if you want the ability to display multiple alerts.

Look at our examples here and see how we're using an array to store them and the HTML code to display them via an ng-repeat.

icfantv
  • 4,523
  • 7
  • 36
  • 53
  • I see. So it fires `close()` 2 seconds after the DOM element is rendered, regardless of its `display` property (which `ngShow` toggles). So when I'm toggling it with the button, it won't trigger the `close()` function. I fixed this by using `ngIf` instead of `ngShow`, which removes/creates the actual DOM node. (This seems like the best fix to me, rather than `ngRepeat`, which also alters the DOM. If you agree, could you update your answer with this info? It also seems like a good idea to document that `dismiss-on-timeout` happens after the DOM element is rendered.) – Adam Zerner Oct 07 '15 at 17:24
  • This has nothing to do with our directive specifically, but rather how Angular processes directives in general. When you use `ng-if` to add components to the DOM, Angular will execute any directive introduced. And `ng-repeat` will do the same thing so you need to decide whether or not you need the ability to show multiple alerts. – icfantv Oct 07 '15 at 17:58
  • Right, but as far as how to get `dismiss-on-timeout` to work how I want it to, `ngIf` still seems like a better solution than `ngRepeat` when there's one alert. It also seems worth noting that `dismiss-on-timeout` calls `close()` in the link function (or however it's happening) rather than being triggered by the display property or something. – Adam Zerner Oct 07 '15 at 18:04
  • Oh. Yes. If you want only one alert at a time then `ng-if` is the way to go. FWIW, the `close` function is executed in a `$timeout` after the delay specified by `dismiss-on-timeout` if the `dismiss-on-timeout` attribute is specified, otherwise, the `close` attribute is ignored. – icfantv Oct 07 '15 at 23:59
0

your are using angular-ui but you are trying to execute native javascript function, try to use the angular in your js file.1 So you need to implement it with so that directive could call it,

  <alert type="danger" close='closeUpdateSuccess()' ng-if="show" 
   dismiss-on-timeout="2000">Something happened.</alert>

and in controller:

$scope.show = true;

$scope.closeUpdateSuccess() = function(index) {
    $scope.show = false;
};
nur farazi
  • 1,197
  • 12
  • 32