From an AngularJS controller, how do I resolve another controller function defined in the module (dynamic ng-controller)?

前端 未结 2 1642
执念已碎
执念已碎 2021-01-15 06:58

Self explanatory fiddle: http://jsfiddle.net/5FG2n/6/

I need to dynamically choose the controller to use at runtime based on its name as a string. The string will b

相关标签:
2条回答
  • 2021-01-15 07:15

    You could try writing custom directive:

    .directive("ngDynamicController",function($compile){
            return {
                terminal: true, 
                priority: 1000,
                link:function(scope,element,attr){
                    var controllerProperty = scope[attr.ngDynamicController];
                    element.attr('ng-controller', controllerProperty);
                    element.removeAttr("ng-dynamic-controller"); 
                    $compile(element)(scope);
                }
            }
        })
    

    If you need more information why we have to add terminal: true and priority: 1000. Check out my answer to this question: Add directives from directive in AngularJS

    DEMO

    You could try injecting it as a value:

    angular.module('app', [])
            .value('InnerCtrl',InnerCtrlAsLocalVariable)
            .controller('OuterCtrl', ['$scope','InnerCtrl', 
            function($scope, InnerCtrl) { //inject the value into the function
                $scope.dynamicCtrl = InnerCtrl;                                          
            }
        ])
    

    DEMO

    Or use $injector to resolve dynamically:

    var InnerCtrlAsLocalVariable = ['$scope',
                function($scope) {
                    $scope.message = 'from controller defined in module - want';
                }
            ]
    
        angular.module('app', [])
            .value('InnerCtrl',InnerCtrlAsLocalVariable)
            .controller('OuterCtrl', ['$scope','$injector', 
                function($scope, $injector) { //inject the $injector service.
    
                    // resolve the value dynamically
                    $scope.dynamicCtrl = $injector.get('InnerCtrl');
    
                }
            ])
    
            .controller('InnerCtrlFromModule', InnerCtrlAsLocalVariable)
    

    DEMO

    You can use $controller service to create the controller instance dynamically, from that instance we can retrieve the constructor function using constructor property

     angular.module('app', [])
            .controller('OuterCtrl', ['$scope','$controller', 
                function(scope, $controller) {
    
                    scope.dynamicCtrl = $controller('InnerCtrlFromModule',{$scope:scope.$new()}).constructor;
    
                }
            ])
    
            .controller('InnerCtrlFromModule',['$scope', function($scope) {
                    $scope.message = 'from controller defined in module - want';
                }])
    

    DEMO

    0 讨论(0)
  • 2021-01-15 07:36

    You don't need to dynamically choose the controller. Use a single controller and use DI to provide different functionality to that controller.

    angular.module('app', [])
        .service('ControllerService', function() {
            this.get = function(controllerName) {
                // ... do your logic for returning the controller functionality here
                if (controllerName == "fooController") {
                    return {
                        foo: function() { return "foo" }
                    }
                }
                else {
                    return {
                        foo: function() { return "bar" }
                    }
                }
            });
        })
        .controller('SingleController', ['$scope', 'ControllerService',
            function($scope, ControllerService) {
                $scope.functionality = ControllerService.get('fooController');
            });
    

    You bind to the functionality object on your controller:

    <div ng-controller="SingleController">
       <p>{{functionality.foo()}}</p>
    </div>
    
    0 讨论(0)
提交回复
热议问题