2

I'm trying to build a string of HTML code inside the directive and then use that as the directive's template.

I tried this but it doesn't work.

myApp.directive('myDirective', [function() {
    return {
        restrict: 'E',
        scope: {
           data: '='      // this is the data that will shape the HTML
        },
        template: str,
        controller: function($scope){
            $scope.str = ****BUILD THE STRING HERE USING 'data'****
        }
    };
}]);

Then I tried passing the app's scope to the directive, but got an error again

myApp.directive('myDirective', ['$scope', function($scope) {
    var str = ****BUILD THE STRING HERE USING $scope.data****
    return {
        restrict: 'E',
        template: str
    };
}]);

I'm confused about how I can do this. In the first example the string is built correctly and when I do

template: {{str}}

I see the string but obviously, it just shows up as text on the page and it's not interpreted as HTML code.

Is there a way to access either myApp's or the directive controller's scope within the return statement of the directive?

I could build the string outside of the directive, but even if I do that I still can't access myApp's scope within the directive.

2
  • 1
    $scope is not a service. You can't inject it into a directve. And I really don"t understand what you want to achieve. A template is a static string. Which is used to generate HTML dynamically based on the data in the scope. Why do you want to generate a string dynamically before passing it as the template of the directive? What are you trying to achieve? Commented May 17, 2017 at 20:04
  • 1
    In short, i have some data in my app. The user is supposed to see different HTML as the data changes. Say, if the data has 100 data points then it should show the data vertically, otherwise it should show it horizontally. i'm trying to build the HTML as a string in JS (using if statements and loops) then show that in the view. What i'm trying to achieve is to make the HTML responsive to changes in the data by making the template itself dynamic. Commented May 17, 2017 at 20:21

2 Answers 2

1

Directives, by nature have access to the outer scope, if you don't strictly define it with an inner scope (or isolated scope). Example:

angular.module('app',[]).controller('ctrl', function($scope) {
  $scope.example = {
    message: "Hello world"
  };
}).directive("myDirective", function() {
  return {
    template: '<strong>{{example.message}}</strong>'
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div my-directive></div>
</div>

As you can see in the example above - The directive "knows" the outer scope values without you need to actually inject it.

Now, you can create an isolated scope and by doing this you don't limit yourself to a given scope:

 angular.module('app',['ngSanitize']).controller('ctrl', function($scope) {
  $scope.example = {
    html: "<strong>Hello world</strong>"
  };
}).directive("myDirective", function() {
  return {
    scope: {
      data: '='
    },
    template: '<div ng-bind-html="data"></div>'
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-sanitize.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div my-directive data="example.html"></div>
</div>

By including ngSanitize I an able to use the ngBindHtml directive and pass an HTML structure to the directive inner scope.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer! I get it now, thanks! I would upvote it but it won't let me :/
0

Strictly speaking what you're trying to do can be achieved by using ng-if to output html that uses different directives based on the data count in your controller. This is better 'separation of concerns', as it means you're moving your presentation logic into the view where it belongs, and your controller is then concerned with your business logic including a data count variable (which you can then use in the ng-if).

If using this approach, you'll want to put your data retrieval into a service that the controller uses, and use the same controller for both directives.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.