0

I'm trying to create a sort of generic toggle feature between directives, where one directive which contains a template does not render, until an event occurs from another directive. Any suggestions on how to link this together?

Thanks!

2
  • 2
    You should provide some code! Commented Nov 23, 2013 at 20:43
  • numerous ways to achieve this....some detail would help Commented Nov 23, 2013 at 21:27

1 Answer 1

2

There are many ways to achieve this.

A

Using events (but be careful, when used exessively, especially for interaction between directives, you can get lost easily! This is why I didnt create a http://plnkr.co for it, even worse:

code A is untested!

so pls edit this in case of errors

  1. Use $rootScope.$on('myEvent', function(e, eargs) {...}) on the master directive.
  2. dispatch the event from some directive: $rootScope.$broadcast('myEvent', {foo: 'bar'}).
  3. remember to inject $rootScope in both directives.
angular.module('masterDirective', [])
  .directive('masterDirective', function ($rootScope, $compile /**injects here*/) {
    var templ = '<p ng-bind="someVar"></p>';
    return {
      restrict: 'EA',
      scope: {},
      link: function (scope, element, attrs) {
        scope.someVar = "I am a template and I was born and visible to the world, because slaveDirective send me an event to do so.";
        $rootScope.$on('myEvent', function(e, eArgs) {
          // eArgs.myVar will be 'Jackson';
          element.append($compile(templ)(scope));
        });
      }
    }
  });

angular.module('slaveDirective', [])
  .directive('slaveDirective', function ($rootScope) {
    return {
      restrict: 'EA',
      scope: {},
      link: function (scope, element, attrs) {
        $rootScope.$broadcast('myEvent', {myArg: 'Jackson'});
      }
    }
  });



B

Using a "shared controller" is the cleaner, but more complicated way. This approach is more strongly typed, you express the workflow and once it works, it is not as easy to break.

Demo: http://plnkr.co/WaqKzP

  1. Use a controller on your master directive: controller(scope,element,attrs) {...}
  2. require your masterDirective in slave directive: require: 'myMasterDirective'
  3. the controller of the master directive is the fourth parameter of your slave's link function (because you required it), you can call a function to let the master include the template.
<body ng-app="myApp">
  <button ng-click="includeSlave=true">include slave directive</button>
  <master-directive>
    <div ng-if="includeSlave==true">
      <slave-directive></slave-directive>
    </div>
  </master-directive>
</body>
angular.module('myApp', [])
.directive('masterDirective', function ($rootScope, $compile /**injects here*/) {
    var templ = '<p ng-bind="someVar"></p>';
    return {
        restrict: 'E',
        controller: function ($scope, $element) {
            return {
                slaveLink: function() {
                    $element.append($compile(templ)($scope));
                }
            }
        },
        link: function (scope, element, attrs) {
            scope.someVar = "I am a template and I was born and visible to the world, because slaveDirective called a function on myself to do so.";
        }
    };
})

.directive('slaveDirective', function () {
    return {
        require: '^masterDirective',
        restrict: 'E',
        link: function (scope, element, attrs, myMasterController) {
            myMasterController.slaveLink();
        }
    };
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.