I want to create a dynamic view directive with a dynamic controller. the controller and view of the template come from the server.
Directive
var DirectivesModule = angular.module('BPM.Directives', []); (function () { 'use strict'; angular .module('BPM.Directives') .directive('bpmCompletedTask', bpmCompletedTask); bpmCompletedTask.$inject = ['$window']; function bpmCompletedTask ($window) { // Usage: // <bpmCompletedTask></bpmCompletedTask> // Creates: // var directive = { link: link, restrict: 'E', scope: { type: '=', taskdata: '=', controllername:'@' }, template: '<div ng-include="getContentUrl()"></div>', controller: '@', name: 'controllername' }; return directive; function link(scope, element, attrs) { scope.getContentUrl = function () { return '/app/views/TasksViews/' + scope.type + '.html'; } scope.getControllerName = function () { console.warn("Controller Name is " + scope.type); return scope.type; } } } })();
This is how I try to use the directive
<div ng-controller="WorkflowHistoryController as vm"> <h2>Workflow History</h2> <h3>{{Id}}</h3> <div ng-repeat="workflowStep in CompletedWorkflowSteps"> <bpm-completed-task controllername="workflowStep.WorkflowTaskType.DataMessageViewViewName" taskdata="workflowStep.WorkflowTaskOutcome.TaskOutcome" type="workflowStep.WorkflowTaskType.DataMessageViewViewName"> </bpm-completed-task> </div> </div>
Now the problem is when the directive gets the name of the controller, it gets it as a literal string, not as a parameter.
Is this doable? if this is not possible, What is the best solution for creating dynamic views using your controllers and dynamically display them inside ng-repeat?
Thanks,
Update January 20 I just updated my code in case someone is interested in it. All credits are sent by @Meligy.
First directive:
(function () { 'use strict'; angular .module('BPM.Directives') .directive('bpmCompletedTask', bpmCompletedTask); bpmCompletedTask.$inject = ['$compile', '$parse']; function bpmCompletedTask ($compile, $parse) { var directive = { link: function (scope, elem, attrs) { console.warn('in the first directive - before if'); if (!elem.attr('bpm-completed-task-inner')) { console.warn('in the first directive'); var name = $parse(elem.attr('controllername'))(scope); console.warn('Controller Name : ' + name); elem = elem.removeAttr('bpm-completed-task'); elem.attr('controllernameinner', name); elem.attr('bpm-completed-task-inner', ''); $compile(elem)(scope); } }, restrict: 'A', }; return directive; } })();
Second directive
angular .module('BPM.Directives') .directive('bpmCompletedTaskInner',['$compile', '$parse', function ($window, $compile, $parse) { console.warn('in the second directive'); return { link: function (scope, elem, attrs) { console.warn('in the second directive'); scope.getContentUrl = function () { return '/app/views/TasksViews/' + scope.type + '.html'; } }, restrict: 'A', scope: { type: '=', taskdata: '=', controllernameinner: '@' }, template: '<div ng-include="getContentUrl()"></div>', controller: '@', name: 'controllernameinner' }; }]);
Html
<div ng-repeat="workflowStep in CompletedWorkflowSteps"> <div bpm-completed-task controllername="workflowStep.WorkflowTaskType.DataMessageViewViewName" taskdata="workflowStep.WorkflowTaskOutcome.TaskOutcome" type="workflowStep.WorkflowTaskType.DataMessageViewViewName"> </div> </div>