What is the best way to organize dynamically loaded directives in angular?

In my project, I have a small div that has 3 options: "food", "drinks", "social". They are bound to the scope variable "$ scope.option" in the "AppController".

I have a number of ng-switch statements:

<div ng-switch on="option"> <div ng-switch-when="food"> <fooddirective></fooddirective> </div> <div ng-switch-when="drinks"> <drinksdirective></drinksdirective> </div> <div ng-switch-when="social"> <socialdirective></socialdirective> </div> </div> 

Please note that regardless of the selected option, food, drink or social, they occupy half the page, so they are all surrounded by the "AppController". My intention is to be able to "dynamically load directives" on the page. Is there a way to get rid of the need to explicitly write "<socialdirective></socialdirective>" or even get rid of the whole ng switch? Or is there some better alternative? It seems like it can get very dirty if I say 20 or 30 of these options (e.g. food, drinks, social games).

If I know the name of the directive in advance, I will say "food", "drinks", "social". Is there a way to do something like:

 <div ng-switch on="option"> // code that interprets option variable (ie food), appends the text "directive" after, and dynamically/lazily add it in and remove it so it behaves like an ng-switch </div> 

I'm not sure if this is possible, but I am looking for a better alternative to what I am doing now. Any examples of a revised way of doing is great.

+6
source share
3 answers

You can use a UI router to accomplish this:

- index.html

 <body> Top Level <div ui-view></div> </body> 

- optionsPage.html

 <select ng-options="option.name for option in data.availableOptions track by option.id" ng-model="data.selectedOption"></select> <div ui-view></div> 

On the options page, you will make selection options that generate ui-sref links for each type of directive that you want to display. A child’s state only changes the ui-representation of their parent state, so you can easily get to the correct directive.

Then you define your routes as such:

  .state('options.food', { templateUrl: "partials/options.food.html" }) .state('options.drinks', { templateUrl: "partials/options.drinks.html" }) 

You can then define a directive in each of these HTML files.

(Most of this code is just taken from the Angular and UI-Router code examples, but hopefully you can see what you need to do.)

UI Router - https://github.com/angular-ui/ui-router

+2
source

If these directives have a lot of common functionality, it seems to me that a better alternative would be to introduce a new directive, for example option directive, which encapsulates this behavior. Thus, you simply insert this directive in html with the selected parameter as an attribute, the ng switch or any other resolution mechanism that you ultimately use will be hidden in the template of this directive, and the general functionality will be implemented in this directive controller. This will not help you get rid of the disgusting part, but at least you will get the opportunity to use most of the implementation and modulate your code.

+1
source

WARNING: I do not give you a full-fledged working answer. I just want to give you an idea of ​​how to do this.

you can create another directive that wraps the original

 .directive("wrapper", function(){ return { scope: {'option': @}, template: '<' + option + 'directive>' + '</' + option + 'directive>' } }) 

and then name it like

If this does not work, you will need to compile html in your similar function, as shown below

  var tmpl = '<' + option + 'directive>' + '</' + option + 'directive>' element.html(tmpl ); $compile(element.contents())(scope); 

which should definitely do it

0
source

All Articles