1

i'm learning how to use Angular Directives to manipulate my HTML. And i have some doubts about it.

I have my hideElementDirective:

var hideElementDirective = function() {

    var hideElement = {
        init: function(element) {
            element.css('display', 'none');
        }
    }

    return {
        link: function($scope, $element) {
            hideElement.init($element);
        }
    }
}

angular.module('app').directive('hideElementDirective', hideElementDirective);

Call in the HTML:

<hide-element-directive> This tag will disappear </hide-element-directive>

Everything perfect.

Lets increase the logic. I have this indicator that will toggle the state of the hide-element-directive, how should i name the indicator, and how should i catch in the directive?

Example:

<hide-element-directive> This tag will hide/show if you click in the indicator element that </hide-element-directive>

indicator element: <button> If you click me i will hide/show the hide-element-directive </button>

There is any convetion for that? Should i use data-* or insert a class name related like class="hide-element-directive-indicator"

Thanks.

1
  • you can transclude the element you want to hide and use a template in directive defenition for making a button as an indicator Commented Aug 15, 2015 at 17:57

2 Answers 2

2

To address your question of naming conventions:

I don't think that there are any established conventions for this situation in particular. There isn't a convention to use data-*. But as always, be sure to follow the best practices of naming in general!


I wouldn't use a directive at all; I would use ngShow:

VIEW

<div ng-show='visible'>Starts off hidden</div>
<button ng-click='toggleVisibility()'>Toggle visibility</button>

CONTROLLER

function controller($scope) {
  $scope.visible = false;
  $scope.toggleVisibility = function() {
    $scope.visible = !$scope.visible;
  };
}
Sign up to request clarification or add additional context in comments.

7 Comments

..., which technically is a directive ;) but yes you're right. don't re-invent the wheel
well, in Front End Masters i learn that controller is for data and directives if for manipulate elements.
This is not a question about how to do or the better way, but how naming elements that directives will manipulate and other elements related with the directive
@AmandaFerrari Sorry, I'm not quite sure what you mean - could you clarify?
well, in Front End Masters i learn that controller is for data and directives if for manipulate elements. That's sort of true, but is misleading. Yes, controllers are for data and yes, directives are for directly manipulating the DOM (if that's what you want to do). But the idea of Angular is that you data-bind your stuff in the view to the data in the controller. So to be clear, they probably meant that direct/manual/imperative manipulation of the DOM should be done in directives, not controllers. Otherwise, just declaratively data bind your stuff in the view to the controller.
|
1

A good way to interact with parent directive is through its controller, via require. This way you aren't attached to its scope and can talk to 'through' nested directives that may have their own scopes.

So, two directives are required for that.

app.directive('hidee', function () {
  return {
    scope: {},
    controller: function ($scope) {
      this.hide = function () {
        $scope.hidden = true;
      }
    },
    link: function (scope, element) {
      scope.$watch('hidden', function (newVal) {
        newVal && element.css('display', 'none');
      });
    }
  };
});

app.directive('hider', function () {
  return {
    require: '^hidee',
    link: function (scope, element, attrs, hideeCtrl) {
      element.on('click', function () {
        scope.$apply(function () {
          hideeCtrl.hide();
        });
      })
    }
  };
});

hidee can live without hider, but not vice versa. And the usage is

<hidee>Hide me with <button hider>hider</button></hidee>

And it will work even with

<hidee>Hide me 
    <isolate-scope-dir>with <button hider>hider</button></isolate-scope-dir>
</hidee>

Regarding conventions, it is a good habit to stick to element/attribute directives (hence the default restrict: 'EA' for directives). And in case of button `hider`` attribute is preferable to element because of button appearance.

I guess that the question is about generic directive interaction and not recreating ngShow/ngHide functionality, so I deliberately don't mention them.

4 Comments

That's exactly what is searching for. Thanks.
yeap, you are right, this is not about ngShow/ngHide, i used a generic example for describe what i was trying to understand.
@estus Very nice example, but I think you could simplify it a little bit and just inject $element in controller: function ($scope, $element). Having access to it, you could get rid of the $watch.
@mrak That's right. $watch is unnecessary there for simple toggling but gives a better perspective. I'm sticking to the convention where controller prepares the scope for linking and defines the methods for require, while link does all DOM-related stuff and interacts with required controllers. It does better job for me in the end than just using either controller or link randomly.

Your Answer

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