3

I have a custom directive <my-configform></my-configform> in which I get a JSON array from an API during the compile stage and dynamically construct the element's DOM from:

angular.module('mymodule').directive('myConfigform', function($http, $compile, $interpolate) {
  restrict: 'E',
  controller: 'ConfigCtrl', // Added as per Craig's suggestion
  compile: function(element) {
    var buildMyForm = function(data) {
      var template = $interpolate('<form role="form">{{form}}</form>');
      var formMarkup;
      // ... build formMarkup from data ...
      // just as a very simple example what it could look like:
      formMarkup = '<input type="checkbox" ng-model="config.ticked"> Tick me';

      return template({form: formMarkup});
    };
    $http.get('/api/some/endpoint').success(function(data) {
      element.replaceWith(buildMyForm());
    });
  }
});

My problem is that the form is not bound to the controller after compilation. The elements are all in the DOM, but the ConfigCtrl controller is not created and no data binding has taken place. How can I tell Angular to bind the controller to my dynamically created form?

3
  • 1
    Have you tried adding the controller attribute to your directive definition? (e.g. controller: 'ConfigCtrl') Or did you use ng-controller at a higher level in your DOM? Commented Sep 20, 2013 at 15:47
  • Adding the controller attribute helped insofar as my ConfigCtrl is now instantiated, but there is still no data-binding between the elements in the form and their respective models in the controller scope. Commented Sep 20, 2013 at 15:55
  • Can you make a Plunker to show the problem? Commented Sep 20, 2013 at 16:22

1 Answer 1

4

You need to compile the generated html inside the post linking function like below:

.directive('myConfigform', function($http, $compile, $interpolate) {
    return {
      restrict: 'E',
      compile: function(element) {
        var buildMyForm = function(data) {
          var template = $interpolate('<form role="form">{{form}}</form>');
          var formMarkup = '<input type="checkbox" ng-model="config.ticked"> Tick me';
          return template({form: formMarkup});
        };
        element.replaceWith(buildMyForm());
        return function(scope, element) {
          $compile(element.contents())(scope);
        };
      }
    };
  });

Here is a working plunker

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.