0

HTML:

<body ng-controller="TestController as _tc">
    <h4>Controllers value:</h4>

    <p>{{_tc.value}}</p>

    <button ng-click="_tc.addInput()">Add Directive Value</button>

    <test-directive></test-directive>
</body>

JS:

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


var testController = function( testService ) {

  this.value = 'Test Value!';

  this.content = '';

  this.addInput = function() {

    testService.add('<input placeholder="Enter value" ng-model="_tc.value" />');

  }

};

var testService = function( $sce ) {

  this.content = '';

  this.add = function( content ) {

    this.content = $sce.trustAsHtml( content );

  }

};

var testDirective = function( testService ) {

  return {

    template:'<h4 ng-if="data.content !== \'\'">If you enter value below it should be bound to the controllers value above because scope is shared but value is not binding</h4><div ng-bind-html="data.content"></div>',
    link: function( $scope ) {

      $scope.data = testService;


    }

  }

};

testService.$inject = ['$sce'];
app.service( 'testService', testService );

testController.$inject = ['testService'];
app.controller('TestController', testController );

testDirective.$inject = ['testService'];
app.directive( 'testDirective', testDirective );

Plunkr: http://plnkr.co/edit/rqnFjtYZ0s4wdOlBpEV1?p=preview

The problem: When the directives content is added the data binding is not working in the directive.

I understand that the dynamically added content is only text and can not bind any values but i don't know how to compile it proper way for it to work as supposed to.

Any help will be really appreciated

guramidev
  • 2,228
  • 1
  • 15
  • 19
  • You need to [`$compile`](https://docs.angularjs.org/api/ng/service/$compile) the HTML. See [this question](http://stackoverflow.com/questions/18157305/angularjs-compiling-dynamic-html-strings-from-database) for example. – fracz Oct 24 '15 at 07:09

1 Answers1

0

I finally figured out how to do so. There are a lot of tutorials about $compile and a lot of answers about $compile, but all of them are really very specific case based allowing no flexibility or a lot of hassle to handle different situations.

The easy and very flexible approach is to use a directive inside a directive for dynamic content which has to be compiled like shown in this plunkr: http://plnkr.co/edit/5QTVKoAyDMJORNeopVib?p=preview

This way you can then just compile whole directive without need to select elements and some other crazy unflexible staff like this:

var contentDirective = function( testService,$compile,$timeout ) {

  return {

    scope: {

      data:'='

    },
    link: function( $scope,$element ) {

      $element.html( $scope.data );

      $compile( $element.contents() )( $scope.$parent );

    }

  }

};

In the plunkr there is a $timeout in the content directive just for presentation purposes, generally it won't be needed when the data will be loaded with some action and not immediately on load like in the example.

guramidev
  • 2,228
  • 1
  • 15
  • 19