I want to dynamically specify a controller based on a config that we load. Something like this:
<div ng-controller="{{config.controllerNameString}}> ... </div>
How do I do this in angular? I thought this would be very easy, but I can seem to find a way of doing this.
The controller in AngularJS is a JavaScript function that maintains the application data and behavior using $scope object. You can attach properties and methods to the $scope object inside a controller function, which in turn will add/update the data and attach behaviours to HTML elements.
The ng-controller directive adds a controller to your application. In the controller you can write code, and make functions and variables, which will be parts of an object, available inside the current HTML element. In AngularJS this object is called a scope.
AngularJS ControllersAngularJS applications are controlled by controllers. The ng-controller directive defines the application controller. A controller is a JavaScript Object, created by a standard JavaScript object constructor.
What you want to do is have another directive run before anything else is called, get the controller name from some model remove the new directive and add the ng-controller
directive, then re-compile the element.
That looks like this:
global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) { return { restrict: 'A', terminal: true, priority: 100000, link: function(scope, elem) { var name = $parse(elem.attr('dynamic-ctrl'))(scope); elem.removeAttr('dynamic-ctrl'); elem.attr('ng-controller', name); $compile(elem)(scope); } }; }]);
Then you could use it in your template, like so:
<div dynamic-ctrl="'blankCtrl'">{{tyler}}</div>
with a controller like this:
global.controller('blankCtrl',['$scope',function(tyler){ tyler.tyler = 'tyler'; tyler.tyler = 'chameleon'; }]);
There's probably a way of interpolating the value ($interpolate
) of the dynamic-ctrl
instead of parsing it ($parse
), but I couldn't get it to work for some reason.
I'm using it in ng-repeat, so this is improved code for loops and sub objects:
Template:
<div class="col-xs6 col-sm-5 col-md-4 col-lg-3" ng-repeat="box in boxes"> <div ng-include src="'/assets/js/view/box_campaign.html'" ng-dynamic-controller="box.type"></div> </div>
Directive:
mainApp.directive('ngDynamicController', ['$compile', '$parse',function($compile, $parse) { return { scope: { name: '=ngDynamicController' }, restrict: 'A', terminal: true, priority: 100000, link: function(scope, elem, attrs) { elem.attr('ng-controller', scope.name); elem.removeAttr('ng-dynamic-controller'); $compile(elem)(scope); } }; }]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With