我已经看到控制器以两种方式声明,如下所示。但是这会产生什么差异呢?
appmodule.controller('Actrl',['$scope',function($scope) {}]);
appmodule.controller('Actrl',function($scope) {});
但是,大多数时候,第一次不起作用。为什么呢?
答案 0 :(得分:5)
两种语法都是相同的,但第一个是首选的(如果你正在缩小你的代码,那么就会有一个错字,见下面的描述)。
Angular根据名称解析依赖关系,因此当您编写appmodule.controller('Actrl',function($scope) {});
语法时,Angular会通过读取参数名$scope
来注入$scope
的依赖关系。但是当您的代码缩小以用于生产级别时,您的代码将变为:
appmodule.controller('Actrl', function(a) {});
现在,Angular将无法使用名称a
来解析依赖项。这就是使用第一种方法即appmodule.controller('Actrl',['$scope', function($scope) {}]);
的原因。现在,当您的代码最小化以进行生产时,您的代码将如下所示:
appmodule.controller('Actrl',['$scope', function(a) {}]);
现在,Angular可以匹配a
为$scope
的基于索引的位置。
您的代码中存在拼写错误,在 function
声明之前不应关闭该列表。
在内联数组注释主题下阅读Dependency Annotation以获取更多相关信息。
Angular调用某些函数(如服务工厂和服务器) 控制器)通过注射器。您需要注释这些功能 注入器知道注入函数的服务。 有三种方法可以使用服务名称注释代码 信息:
- 使用内联数组注释(首选)
- 使用$ inject属性注释
- 隐含地来自函数参数名称(有警告)
修改强> 关于两种不同风格的另一个更详细的描述:a-note-on-minification:
因为Angular从名称中推断出控制器的依赖关系 控制器的构造函数的参数,如果你是 缩小PhoneListCtrl控制器的JavaScript代码,全部 函数参数也将被缩小,并且依赖性 注入器无法正确识别服务。
我们可以通过使用名称注释函数来克服这个问题 依赖关系,以字符串形式提供,不会被缩小。 有两种方法可以提供这些注射注释:
答案 1 :(得分:3)
[编辑]
对于您的第一种情况,这不是正确的语法。正确的是将依赖注入和控制器封装在同一个数组中,如下所示:
appmodule.controller('Actrl',['$scope', function($scope) {}]);
两个定义之间的区别在于,在第一种情况下,您将明确指定注入依赖项。这将避免在缩小期间重命名变量名称,这会破坏您的代码。因此引号中的名称[即这些字符串]将用于缩小版本。
两种方法都做同样的事情,但第二种方法只是第一种方法的语法糖。
答案 2 :(得分:2)
这只是AngularJS进行Dependancy Injection的两种方式。但是这个版本,
appmodule.controller('Actrl',['$scope',function($scope) {}]);
特别是为了处理代码缩小而编写的。建议尽可能使用此版本。
为了明确区别,您必须首先了解AngualarJS如何进行依赖注入。有关详细信息,请参阅:
但简而言之,AngularJS通过参数列表中的名称循环遍历每个项目,查找可以注入的已知对象名称列表,然后在匹配时注入对象。< / p>
我们来看一个例子:
appmodule.controller('myController',function($scope, $log) {
$log.info($scope);
});
此处,由于$scope
和$log
(您在参数列表中指定它们的顺序无关紧要)是AngularJS的已知对象,它会将它们注入进入myController
。但如果你这样做:
appmodule.controller('myController',function(someVar) {
// ...
});
AngularJS不知道参数someVar
,它会引发依赖性错误。
现在让我们回到你的例子。让我稍微修改你的第二版:
appmodule.controller('Actrl',function($scope, $log) {
$log.info($scope);
});
如果我们使用minifier,让我们看看这段代码是如何被缩小的。我为此目的使用online minifier。缩小后,它变为:
appmodule.controller("Actrl",function(o,l){l.info(o)});
这是因为,minifiers通常会将变量名缩短为最小尺寸以节省空间。注意我们$scope
如何重命名为o
和$log
改为l
。
现在,如果我们运行此代码,AngularJS不会知道o
和l
,并且我们会在前面已经理解的情况下对缺少的依赖关系感到愤怒。
AngularJS在您的示例中使用第一版依赖注入处理此问题。如果是:
appmodule.controller('Actrl',['$scope','$log', function($scope, $log) {
$log.info($scope);
}]);
缩小后,它变为:
appmodule.controller('Actrl',['$scope','$log',function(o,l){l.info(o)}]);
此处,即使$scope
和$log
参数分别重命名为o
和l
,缩小器也不会触及字符串'$scope'
和{ {1}}及其在数组中的顺序。
现在,当AngularJS注入器使用数组看到此版本时,它会将函数中参数列表中的每个项目替换为数组中的相应对象(前提是AngularJS已知对象)。
因此,在我们的示例中,即使在缩小之后,AngularJS也知道它需要将'$log'
替换为o
而将$scope
替换为l
。因此代码运行时没有任何Dependancy Injection错误。
但重要的是要注意的是,当我们使用这个版本时,数组中指定的项目的顺序和函数的参数列表确实很重要。也就是说,如果你这样做:
$log
,它会把一切都搞砸了!