通过控制器名称以角度访问控制器构造函数

时间:2017-04-21 20:39:27

标签: angularjs angularjs-directive

我有一个控制器名称作为字符串,我想得到它的构造函数。

我目前的方法是使用$ controller如下:

$scope.myControllerConstructor= $controller( "myControllerName" , {$scope: $scope.$new()}).constructor;

稍后,我在html中使用这个构造函数,如下所示:

<div ng-controller="myControllerConstructor">

问题是我的控制器运行两次,一次是我获取构造函数(这是错误的)和一次我的html编译(这是正确的)

问题是如何在不运行控制器构造函数的情况下获取它?

关于用例的更新:在我们的应用程序中,我们有许多页面具有60%的相似性和40%的不同活动。我为这些页面创建了一个指令,团队中的其他开发人员正在使用我的指令来创建他们的页面。

该指令接受模板和控制器(我将它们作为字符串),稍后我将提供的模板和控制器包括在内,如下所示:

<div ng-include="myTemplate" ng-controller="myControllerConstructor"></div>

请查看this jsfiddle以获取一个简单的问题示例。

2 个答案:

答案 0 :(得分:1)

您的代码结构看起来不错,但问题是$controller( "myControllerName" , {$scope: $scope.$new()})已经为您实例化了具有给定范围的控制器。

您可以使用.constructor访问控制器构造函数,但由于您已经创建了控制器实例,因此为时已晚。

ng-controller$controller( "myControllerName" , {$scope: $scope.$new()})

完全相同
  

当Controller通过ng-controller连接到DOM时   指令,AngularJS将使用实例化一个新的Controller对象   指定的Controller的构造函数。一个新的儿童范围   将被创建并作为注射参数提供给   Controller的构造函数作为$ scope。

要解决此问题,您应该将控制器构造函数传递给pageDirectiveTemplate而不是控制器名称。

working fiddle

答案 1 :(得分:0)

我们可以通过不同的方式实现这一目标。在指令中,当使用隔离范围(就像你在小提琴中这样做)时,你可以拥有一个值为controller的属性"@",并拥有另一个name属性,其值为{{ 1}}或者你传递的控制器名称。

所以,你的指令看起来像这样:

"myController"

请注意,只有HTML的更改才能将指令作为属性而不是元素。所以,

app.directive('pageDirective', function() {
  return {
    restrict: "A",
    templateUrl: "pageDirectiveTemplate",
    scope: {
      myTemplate: "@"
    },
    controller: "@",
    name: "myController"
  }
});

这将为您提供您正在寻找的东西。现在,您可以使用相同的模板指向不同的控制器,反之亦然。

working fiddle |请注意,它适用于具有相同模板的两个不同控制器。另外,检查控制台以查看它如何仅从每个控制器记录一次。