0

I need to create a directive which allows data passed in to contain angular expressions, such as the contrived example below (Codepen):

<div ng-controller="ctrl"> <list-test data="data"></list-test> </div> 

Where data is defined as:

app.controller('ctrl', ['$scope', function($scope) { $scope.data = [ '<input type="text" ng-model="testModel">', '{{testModel}}' ]; }]); 

And my directive looks like:

app.directive('listTest', ['$sce', function($sce) { return { restrict: 'E', scope: { data: '=' }, template: [ '<ul ng-repeat="item in data">', '<li ng-bind-html="escape(item)"></li>', '</ul>' ].join(''), link: function(scope) { scope.escape = function(item) { return $sce.trustAsHtml(item); }; } }; }]); 

I've tried modifying my linker to run the item through the compiler but this causes errors. I do know about ng-transclude but it doesn't fit my particular use case.

2
  • maybe you need to try to use components, and try to limit the use of html generation. Remember angular doesn't bind your {{testModel}} inside the data var
    – Joao Polo
    CommentedSep 8, 2016 at 17:06
  • Use the $compile service in the link function to add html that has AngularJS directives and scope bindings.
    – georgeawg
    CommentedSep 9, 2016 at 15:24

1 Answer 1

1

Do something like:

scope.$watch("htmlList", function(value) { if (value) { childScope = scope.$new(); childElement = $compile(htmlString(value))(childScope); elem.append(childElement); } }); 

Of course it gets more complicated if it is more than a one-time binding. In which case the code needs for remove the previous child element and destroy the previous child scope.

The DEMO on JSFiddle.

1
  • Is there a way to do this without forgoing the template? My actual directive is quite complicated and having things in the template really simplifies everything.
    – konapun
    CommentedSep 9, 2016 at 18:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.