2

I have a directive which uses a custom jQuery Plugin, The plugin returns template html to show some list and it works good, BUT when I try to also use an AngularJs directive inside that template something like "ng-click" or one of my custom directives it just does not pick it up.

When I open the source in firebug or chrome debugger tools I can see there is no class="ng-scope" appended to that div which usually is the case in correctly working angular controlled divs. But I see this div is in hiearchialy under the main ng-app div, so I thought it must be inherited to all child divs.

Again This controller and directive works, the only NOT working part is the ng-click which I added to result template from inside the jQuery plugin. Any ideas what is the problem here?

myApp.directive("myDirective", function(){
  return{
    restrict: 'A',
    link: function(scope, element,attrs) {

        $(element).selectAutoComplete({
            dataSourceDelegate: scope.dataSource1,
            dataSourceObject: { value: "id", display: "title"},
            resultTemplate: '<div>show some data as list</div> <div id="internalTemplate"
                                ng-click="doSomething()"> Show Next </div>'
        });
    }
  }
});

and in Html

   <div ng-controller="myController">
            <input my-directive type="text" />
        </div>
Spring
  • 11,333
  • 29
  • 116
  • 185
  • AngularJS needs to compile the template before it can put watches and support data binding to scope method and properties. For dynamically added DOM one needs to use `$compile` service, but since the dom is being manipulated by jquery plugin, you cannot compile what gets injected. – Chandermani Sep 06 '13 at 10:24
  • @Chandermani so even using $compile there is no way I can use any angular directives in that template? – Spring Sep 06 '13 at 10:41
  • I think so. Since the plugin is injecting the template, you don't have a control. You need to muck with the plugin to find how it injects template. If jquery plugin can take a compiled template (which is a angular element) it may work. – Chandermani Sep 06 '13 at 10:49

1 Answers1

2

For dynamically generated HTML you need to use the $compile service like $compile(element)(scope); to get it recognised by angular.

It's more difficult if the plugin is generating the HTML. In my experience most complex plugins have their own API that includes a callback or way to notify you when they're ready. I'd have a look at the plugin docs and see if there's a way to do this (or change it's source to do it yourself if not).

myApp.directive("myDirective", function($compile, $timeout){
return{
restrict: 'A',
link: function(scope, element,attrs) {

    $(element).selectAutoComplete({
        dataSourceDelegate: scope.dataSource1,
        dataSourceObject: { value: "id", display: "title"},
        resultTemplate: '<div>show some data as list</div> <div id="internalTemplate"
                            ng-click="doSomething()"> Show Next </div>'
    });

    // example of what plugin callback could be like - check their docs
    element.selectAutoComplete("finished", function() {
        $compile(element)(scope);
    });

    // if not, using $timeout is a fallback that will mostly work but not ideal
    $timeout(function() {
        // wait for plugin to complete...
        $compile(element)(scope);
    }, 2000);
}
}
});

BTW, you don't need to do $(element) as element is already a jquery object anyway.

Michael Low
  • 24,276
  • 16
  • 82
  • 119
  • tnx so the "only" problem is to know when jquery is done with the template, after that I can safely use $compile, right? – Spring Sep 06 '13 at 15:48