Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Manually Render Controller and Template

I'm trying to implement a plugin system in angularjs that would allow users to configure which "widgets" they will see on a certain page. Each widget is defined by a controller and a template(url). Is it possible to create a directive that instantiates a controller, invokes it with a template and transcludes the resulting content?

The goal is something like this:

<div class="widget" ng-repeat="widget in widgets">     <widget controller="widget.controller" templateUrl="widget.templateUrl"></widget> </div> 
like image 737
LorenVS Avatar asked May 02 '13 16:05

LorenVS


1 Answers

There are two ways to do this; one uses the helper directives already available (like ngInclude and ngController) and the second is manual; the manual version might be faster, but I cannot be sure.

The Easy Way:

The easy method is to simple create a new element with ngController and ngInclude attributes, append it to the directive's element, and then $compile it:

var html = '<div ng-controller="'+ctrl+'" ng-include="'+tpl+'"></div>'; element.append(html); $compile( element.contents() )( scope ); 

The Manual Way:

The manual way is to do what these directives would themselves do in turn; this logic is very similar to what ngView does (though without the complexity). We fetch the template, storing it in $templateCache, and then append it to the DOM. We create a new child scope and instantiate the provided controller with it and assign that controller to the element. Finally, we $compile it:

$http.get( tpl, { cache: $templateCache } ) .then( function( response ) {   templateScope = scope.$new();   templateCtrl = $controller( ctrl, { $scope: templateScope } );   element.html( response.data );   element.children().data('$ngControllerController', templateCtrl);   $compile( element.contents() )( templateScope ); }); 

(Note that there is no garbage collection here, which you would need to implement if the widgets change)

Here is a Plunker demonstrating both methods: http://plnkr.co/edit/C7x9C5JgUuT1yk0mBUmE?p=preview

like image 128
Josh David Miller Avatar answered Sep 22 '22 13:09

Josh David Miller