我是angular.js
的新手,并经历了几个教程,包括 codeschool 上的所有教程。我发现它们非常有用,并且学到了很多东西。但是现在我已经完成了我的“介绍”并开始尝试在某些方面使用它,我发现了一些令人困惑的不一致,最明显的是“依赖注入”。
在我参考的教程中,服务的依赖关系是这样完成的;
app.controller('name', [ $http, $scope, function($http, $scope) {
// .. code ... //
}]);
这让我感到很奇怪,但无论如何它仍然有效。我很困惑为什么[]
在函数之前没有终止(我强<假> 这就是你所说的'回调'函数JavaScript的?)。我期待它更像require.js
本来就是......
app.controller('name', [ '$http', '$scope' ], function($http, $scope) { });
然而,我开始查看角度在线的示例和演示,我发现这不一致。例如,检查以下链接;
在每一个中,我都看到依赖注入像这样使用;
app.controller('name', function($http, AdvancedGithubUser) { });
app.controller('name', function($scope){ });
function controllerName($scope) { };
他们完全绕过array
类似的语法,三者都不同。在一个,它需要一种在其他地方声明的对象,但我没有看到任何布线指向它。
另一方面,它只是有这些对象。
仍然在另一个中,controller
的'name'部分是函数的名称,我没有看到任何真正表示为controller
的东西,但它在指令。
任何人都可以向我解释这个吗?我现在完全迷失了。这种不一致使得采用这些技术有点困难。
答案 0 :(得分:6)
有三种方法可以注释函数的依赖关系:
第一个是:使用参数名称显式且准确:
app.controller('ACtrl', function($scope, $http, $q) {
//your stuff here
});
这意味着该函数具有必须与已注册的服务/提供者的名称匹配的参数名称。 警告:如果你缩小文件(uglify,以节省空间),你将丢失参数名称,因此它将被破坏 - 不起作用(会抱怨)。
第二个允许您选择要作为字符串文字注入的服务名称(因为字符串文字是一个值,它永远不会缩小):
var myfunc = function($s, $http, $q) {
//do your stuff here
};
myfunc.$inject = ['$scope', '$http', '$q'];
app.controller('ACtrl', myfunc);
这使Angular读取函数的$ inject属性,并且不是按名称匹配形式参数,而是按相同数组位置的值匹配。因此,即使您缩小文件,$ scope也将以$ s为单位。如果函数中不存在$ inject,那么你将回到第一个 - 而不是推荐 - 的情况。
第三个类似于第二个(即它将通过字符串指定依赖关系并且将抵制丑化):
var myfunc = function($s, $http, $q) {
//do your stuff here
}
app.controller('ACtrl', ['$scope', '$http', '$q', myfunc]);
请注意,数组的最后一个元素是要调用的函数。它看起来有点令人毛骨悚然,但它是一致的。 Angular这样做:如果控制器是一个数组,则弹出最后一个元素 - 它将是函数。前面的元素(剩下的数组)与函数中的$inject
值完全相同。
控制器和提供者必须有一个名称来引用它们 - 我使用'ACtrl'作为控制器的名称。它不是函数的名称,而是在依赖注入(对于提供者)和诸如ngRoute(对于控制器)之类的东西中使用的内部名称。
声明名称是您要求的接线的第一个界限。在三种形式的依赖注入中使用它们是这种布线的第二种结合。
记住:AdvancedGithubUser
是注册提供商,$http
也是如此。唯一的区别是$http
内置在Angular中,而AdvancedGithubUser不是。美元符号起始符号应该保留给Angular,但这不是一个要求 - 只是一个好习惯。 AdvancedGithubUser
已创建(在外部模块中),类似于:
app.service('AdvancedGithubUser', AdvancedGithubUser);
//being AdvancedGithubUser a constructor.
答案 1 :(得分:4)
两个
myApp.controller('ACtrl', ['$scope', function($scope) { }])
和
myApp.controll('ACtrl', function($scope) { });
是允许的。但是,根据docs,建议使用第一种方法(数组表示法)。
“这可以避免为控制器创建全局函数,也可以防止缩小”。
答案 2 :(得分:1)
您可以使用直接依赖注入(如链接)或命名依赖注入(使用数组)。
我建议将命名语法作为最小化器,例如uglify将压缩变量名称。使用数组,您可以将对象命名为inject,然后将(最后一个参数,函数)命名为您使用它,因此在变量压缩后,angular仍将知道您想要的对象。