AngularJS: element.show () on directive not working

I have a directive ( see plunk ) that wraps a DIV with a style display:none

and shows its contents after one second. I tried to show it with element.show () and $ (element) .show () elements (including jQuery) but it never worked. Timeout is working, what is wrong with this code?

This is HTML:

    <hideme>
      Show this after one second
    </hideme>

      

and this is javascript:

angular.module("app", []);

function MyCtrl($scope) {}

angular.module("app").directive('hideme', function($timeout) {

    return {

        restrict: 'E',
        template: '<div style="display: none !important"></div>',
        link: function(scope, element, attrs) { 
            $timeout(function() {
                  element.show();
            }, 1000);
        }
   };
});

      

+3


source to share


5 answers


Plunker: http://plnkr.co/edit/bzhCwjXdll3ibxc7qsMY?p=preview

Try using transclude: true and then ng-transclude to display markup between custom element tags. Also, I'm not familiar with using show (), so instead set html ng-show = 'showEl' and define showEl = true on timeout.



angular.module("app", []);

function MyCtrl($scope) {}

angular.module("app").directive('hideme', function($timeout) {

    return {
          transclude: true,
        restrict: 'E',
        template: '<div ng-show="showEl"><div ng-transclude></div></div>',
        link: function(scope, element, attrs) { 
            $timeout(function() {
                  scope.showEl = true;
              }, 1000);
        }
    };
});

      

+1


source


The item is shown, the problem is that it does not contain anything to show. Also, to have a show function, you need to add a jQuery dependency and apply it to the correct div.

angular.module("app", []);

function MyCtrl($scope) {}

angular.module("app").directive('hideme', function($timeout) {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div style="display: none;"><div ng-transclude></div></div>',
    link: function(scope, element, attrs) {
      $timeout(function() {
        element.find("div:hidden").show();
      }, 1000)
    }
  };
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <hideme>
    Show me after one second.
  </hideme>
</div>
      

Run codeHide result




It said. I would do it like this:

angular.module("app", []).directive('hideme', function($timeout) {
  return {
    restrict: 'E',
    transclude: true,
    scope: true,
    template: '<div ng-show="show"><div ng-transclude></div></div>',
    link: function(scope, element, attrs) {
      scope.show = false;
      $timeout(function() {
        scope.show = true;
      }, 1000)
    }
  };
});
      

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <hideme>
    Show me after one second.
  </hideme>
</div>
      

Run codeHide result


+4


source


  • The template is inserted into your own tag, so yours <div>

    becomes a child of the tag <hideme>

    .

  • In the link () function, the argument element

    is a tag <hideme>

    , not a tag <div>

    , so displaying the tag <hideme>

    does not display the child <div>

    that was created with display: none

    . In other words, if you have this:

    <hideme style="display: block"> <div style="display: none">Show this in three seconds.</div> </hideme>

    which does not display <div>

    .

  • If you are not loading jQuery before loading angularjs then angularjs uses something that it calls jqLite to wrap the elements. Wrapped elements act like jQuery wrapped sets, but they have reduced functionality, eg. show () and hide () are not provided.

So if you load jQuery and then load angularjs you can do this:

app.js:

var app = angular.module('myApp', []);

app.directive('hideMe', ['$timeout', function($timeout) {
  var directive = {};

  directive.restrict = 'E';

  directive.link = function(scope, element, attrs) {
    element.html(
      '<div style="display:none">' 
      + element.text() 
      + '</div>'
    );

    $timeout(function() {
      element.children().show();
    }, 3000);

  };


  return directive;
}]);

      

index.html

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

<head>
  <!-- For html5 (default is UTF-8) -->
  <meta charaset="UTF-8">
  <!-- For Bootstrap -->
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>AngularJS Examples</title>

  <!-- Bootstrap CSS -->
  <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
  <!-- app.css -->
  <link href="app.css" rel="stylesheet">

</head>

<body class="container">

   <hide-me>Show this after three seconds.</hide-me>



<!-- JQuery 2.1.1 -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Angular 1.3.3 -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>

<!-- app.js -->
<script src="app.js"></script>

</body>
</html>

      

However, I noticed that the text flashes briefly on the page before disappearing. Edit: If I replace element.text()

with element.html()

then there is no flash.

On the other hand, if you are not loading jQuery, you can do this:

var app = angular.module('myApp', []);

app.directive('hideMe', ['$timeout', function($timeout) {
  var directive = {};

  directive.restrict = 'E';

  directive.link = function(scope, element, attrs) {
    var hideme = element[0];
    hideme.innerHTML = '<div style="display:none">' + hideme.innerHTML + '</div>';

    $timeout(function() {
      var div = hideme.childNodes[0];
      div.style.display = "block";
    }, 3000);

  };


  return directive;
}]);

      

Then the text doesn't flash on the screen before hiding.

+4


source


.hide () and .show () only work if jquery is inserted before angular in your html file.

Gwenn

+3


source


You can simply use the following without including jQuery to render the element:

element.css('display', 'block');

      

And hide corresponding to it:

element.css('display', 'none');

      

+2


source







All Articles