如何动态地将本机注入控制器?

时间:2015-06-17 18:30:56

标签: angularjs

我们大多以这种方式编写控制器:

app.controller('MyCtrl', function($scope, $location) {
//do something with $scope & $location
});

我正在写一个指令,我面临一个场景,我必须根据某个控制器实例渲染一个视图。该指令将按如下方式调用:

<my-directive src="srcVar" controller="myctrl"></my-directive>

该指令负责加载srcVar指定的模板,并使用$ controller服务实例化控制器。所以我的代码中几行代码如下:

$controller(çtrlExp, {'$scope' : scope.$new() });

以上适用于控制器只有一个参数的简单情况。对于上面的控制器示例,您可以按以下方式填充:

var locals = { '$scope' : $scope.$new(), '$location' : $injector.get('$location') };
$controller('MyCtrl', locals);

现在如何为通用案例编写它,其中用户的控制器可以包含任意数量的可注入构造,如服务,值,常量等,所有这些通常在模块创建期间定义。

Ps:如果你正在寻找可行的代码......请参考我的github回购:https://github.com/deostroll/ngFrame/blob/master/app/scripts/viewutils.js。这仍然是一种正在进行中的工作。

1 个答案:

答案 0 :(得分:0)

您只需要在当地人中添加$scope,其余部分将由Angular的DI自动完成。

请查看下面的演示或此jsfiddle

angular.module('demoApp', [])
.controller('mainController', MainController)
.directive('myDirective', MyDirective);

function MainController($scope, $location) {
    this.testTemplate = 'testTemplate.html';
    console.log($location, $scope); // everything available here!
}

MainController.$inject = ['$scope', '$location'];

function MyDirective($compile) {
    return {
        restrict: 'E',
        template: 'hello',
        controller: function($scope, $attrs, $controller){
            console.log($attrs.controller, $scope);
            $controller($attrs.controller, {'$scope': new $scope.$new()});
        },
        compile: function(element, attrs, $scope) {
            var template = angular.element(document.getElementById(attrs.src))
                .html();
            
            console.log(template);
            element.replaceWith(template);
            
            return function(scope, element, attrs) {
                //template is compiled now and in DOM, add scope variable
                scope.hello='Hello from directive';
            };
        }
    };
}

MyDirective.$inject = ['$compile'];
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp">
    <script type="text/ng-template" id="testTemplate.html">
        <div>
            <h1>Test template</h1>
            {{hello}}
        </div>
    </script>
    <my-directive src="testTemplate.html" controller="mainController"></my-directive>
</div>