1

I'm working on building a dashboard in AngularJS, and I have created a "widget" directive. The problem is that the widget can be one of multiple types of widgets, and I'm varying that based on a certain property on the directive. This is really easy for templates, where I can just get the attribute from the attributes object in the link function, fetch a template, and compile it.

However, for the controller, it seems to be more difficult (or I'm just missing it). What I have so far is this:

return ['$compile', '$http', function($compile, $http) {
    var templateContent = '';

    return {
        restrict: 'A',
        scope: {},
        link: function($scope, element, attributes, controller) {
            element.append($compile(templateContent)($scope));
            ...
        }
    };
}];

I'm looking for a way to set the controller dynamically based on an attribute on the element. Is this possible? I don't want to explicitly set data-ng-controller on the element because I'm trying to get the HTML to only include the TYPE of widget it wants to load (not having to worry about the template location or controller for it).

Ideally, it'd look something like this:

<div data-widget="typename">...</div>

1 Answer 1

1

There's more than way to do this. I've made a drill-down-able dashboard out of AngularJS, myself, heh, and I had a similar issue.

The easiest is to probably just use a naming convention. So whatever the widget is called, be it a "PieChartWidget" or whatever - you will just concatenate that with "Controller" (or whatever suffix you use for your controllers) and put that as the value for an ng-controller attribute that you call $compile on in your directive.

If you don't like convention-based things you could make a service called "widgetControllers" that acts like a dictionary and, inside run blocks, register each type of widget with the name of its controller with the service. Then, inside your directive above, request the service and just look up the name of the controller to use.

And finally you should consider (if you haven't already - this is what I did) making a directive for each type of widget instead of a controller/template combo. Then basically have a generic-widget directive that will look at its type attribute and create an element of the correct directive using one of the two approaches above (convention or service-dictionary). This generic widget can take in the both the data of the widget (i.e. the table) and the configuration (i.e. colors, x-axis formatting, etc.) and pass those into the directive it creates. This is especially useful for what I did as one widget could contain other widgets recursively.

If you need any further clarification or would like a fiddle or something demonstrating any of the aforementioned concepts, let me know.


EDIT

Someone wanted an example, so here it is.

http://plnkr.co/edit/UEOogOpuX2cE951arRAY?p=preview

Sign up to request clarification or add additional context in comments.

3 Comments

I never thought about a generic directive that renders elements with the other directives. Don't know how it never occurred to me! Going to test it out. I'll report back shortly.
Words Like Jared can you throw together a quick fiddle. I'm new to using the compile directive.
Just made one :) If you have any more questions consider making a new SO question if appropriate.

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.