Which template to use for different AngularJS directives in ng repeat based on dynamic data

I am building a dynamic panel from a data array. Gauges D3.

I have a selection of different D3 sensors defined in AngularJS directives. On my page, I have ng-repeat over an array of metrics.

The question I have is the best way to dynamically select the right directive based on the data attribute in the ng-repeat array?

Is there a way to create a factory pattern where the Directive used is based on an input value from an array? Or is there a way to achieve the result using only directives dynamically, including other directives in the directive?

HTML

<div ng-controller="DashboardCtrl"> <div id="oppChart"> <div> <gh-visualization ng-repeat="item in metrics" val="item[0]"></gh-visualization> </div> </div> </div> 

Array of indicators (will be dynamic):

 $scope.list = [ { 'title': 'XYX','data-type':'', 'query':'SELECT ...' }, { 'title': 'Revenue', 'data-type':'', 'query':'SELECT ...' } ]; 

D3 directive based on this - http://briantford.com/blog/angular-d3.html

+6
source share
3 answers

It will be ng-switch

 <div ng-repeat="item in metrics"> <div ng-switch on="item.type"> <div ng-switch-when="optionA">..include </div> <div ng-switch-when="optionA">..include </div> </div> </div> 
+6
source

Yes, I did it, as you described in your second option.

I created a directive that loads a specific template, which then contains other directives based on a data type attribute.

  directive("dynamicFormInput", ['$http', '$templateCache', function($http, $templateCache){ return { restrict: 'E', //currently need model for map center otherwise can be removed, need to set default in map directive scope: {model: '=', section: '='}, template: '<ng:include src="tpl"></ng:include>', link: function(scope, iElement, iAttrs) { var sectionToLoad = ""; switch(scope.section.sectionTypeId) { case 1: sectionToLoad ='partials/survey/textInput.html'; break; case 2: sectionToLoad = 'partials/survey/selectOneOption.html'; break; case 3: sectionToLoad = 'partials/survey/multiSelectOption.html'; break; case 4: sectionToLoad = 'partials/survey/boolean.html'; break; case 5: sectionToLoad = 'partials/survey/textInput.html'; break; case 6: if(scope.section.sectionId == 13) sectionToLoad = 'partials/survey/addressSelection.html'; else if(scope.section.sectionId == 24) sectionToLoad = 'partials/survey/contactForm.html' break; } if(sectionToLoad!="") { $http.get(sectionToLoad, {cache:$templateCache}); scope.tpl=sectionToLoad; } } } }]) 

Usage then looks like:

 <accordion close-others="true"> <accordion-group ng-repeat="section in sections" ng-class="{'isGroundTruthed':section.userId==73}" heading="{{section.sectionName}} ({{displaySelection(section)}})"> <dynamic-form-input section="section"> </dynamic-form-input> </accordion-group> </accordion> 

You can ignore the accordion that I just used to somehow repeat it so that each section develops.

Edit Just cleared my directive code.

+1
source

Your second solution sounds more angular - suitable. So if its just one directive that is added dynamically

 app.directive('dynamically',function(){ return { restrict: 'A', compile: function(element,attrs){ var directives = []; if (attrs.dynamically.indexOf(' ') > -1){ directives = attrs.dynamically.split(' ') } else { directives.push(attrs.dynamically) }; var html = '<ANY '; for (var i in directives){ html += directives[i] + '="true" '; }; html += '></ANY>'; element.replaceWith(html) } } }) 

This is one way to do this.

1) if (attrs.dynamically.indexOf(' ') is that you can implement multiple directives in one instance, separated by a char ('') space in this example.

2) I add '= "true"' for the attribute that I am working with by setting if (attrs.x) {...} if the attribute x does not matter, it does not exist even if it is specified and is in the DOM.

0
source

Source: https://habr.com/ru/post/953356/