0

I have the following problem. I have a custom directive with some content. There is a spacial place inside this directive that should be dynamic (some custom functionality).

The directive looks something like this:

var app = angular.module('plunker', []);
app.directive('mydirective', mydirective);
function mydirective() {
    return {
        restrict : "E",
        scope : {
         customContent: '@'
        },
        template : "<div>Some common directive stuff in here!   <div id='customContent'></div></div>",
        compile: function(element, attr) {
            return {
                post: function($scope, element, attr) {
                    console.log("POST");
                },
                pre: function($scope, element, attr) {
                    console.log("PRE: " + $scope.customContent);
                            if($scope.customContent) {
                                var customContent = (angular.element(document.getElementById('customContent')));
                                customContent.append($scope.customContent);
                            }
                }
            };
        }
    }
}

As you can see there is a div tag with id='customContent'

Now whenever I use this directive from a controller, I would like to be able not only to inject special custom content inside this directive, but also to provide the scoping functionality.

The required result should be:

controller

app.controller('MainCtrl', function($scope) {
   $scope.func = function() { // THIS DOESN'T WORK
      alert(1);
   }
});

html

<mydirective custom-content="<button ng-controller='MainCtrl' ng-click='func()'>Test</button>"></mydirective>

As you can see I am injecting the passed custom-content as parameter in the PRE linking function. Unfortunately I was not able to hook the func() function into the controller's scope, because that's the place that I would like to be able to control the things from.

Thank you in advance for any help!

This is the plunker: https://plnkr.co/edit/I4WAQ20ugeDiackxXqUz?p=preview

kirilv
  • 1,373
  • 1
  • 18
  • 24
  • pass the function into isolated scope with another attribute – charlietfl Sep 15 '16 at 18:37
  • This would work, but I am simply showing a simple example with a single function. Imagine that the custom template contains multiple function calls. Not only that; I might plug a totally different content from within another controller that uses this directive. – kirilv Sep 15 '16 at 18:44

2 Answers2

1

You can use ng-transclude to insert content inside your directive while still having access to the parent controller's scope.

Further reading on ng-transclude:

Community
  • 1
  • 1
Aaditya Sharma
  • 3,330
  • 3
  • 24
  • 36
1

This should do what you want:

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

app.controller('MainCtrl', function($scope) {
  $scope.func = function() {
    alert(1);
  }
});

app.directive('mydirective', mydirective);

function mydirective() {
        return {
            restrict : "E",
            transclude: true,
            scope : {

            },
            template : "<div>Some base directive stuff in here!   <ng-transclude></ng-transclude></div>",

        }
    }

and

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

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">

      <mydirective><button ng-controller='MainCtrl' ng-click='func()'>Test</button></mydirective>

  </body>

</html>

Working plunker

Neil
  • 2,659
  • 7
  • 35
  • 57