对AngularJS依赖注入不一致感到困惑 [英] Confused about AngularJS dependency injection inconsistency

查看:77
本文介绍了对AngularJS依赖注入不一致感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 angular.js 的新手,并经历了几个教程,包括 codeschool 即可。我发现它们非常有用,并且学到了很多东西。但是现在我已经完成了我的介绍并开始尝试在某些方面使用它,我发现了一些令人困惑的不一致,最明显的是依赖注入。



<在我学习的教程中,服务的依赖关系是这样完成的;

  app.controller('name',[$ http,$ scope,function($ http,$ scope){
// .. code ... //
}]);

这让我觉得很奇怪,但无论如何它都有效。我很困惑为什么 [] 在函数之前没有终止(我强<假> 这就是你所指的 javascript中的'回调'功能?)。我期待它更像是 require.js 它本来就是......

  app.controller('name',['$ http','$ scope'],函数($ http,$ scope){}); 

然而我开始查看角度在线的示例和演示,我发现这不是是一致的。例如,检查以下链接;





在每一个中,我都看到依赖注入像这样使用;

  app.controller('name',function($ http,AdvancedGithubUser){}); 
app.controller('name',function($ scope){});
函数controllerName($ scope){};

他们完全绕过数组之类的语法,这三者都不同。在一个,它需要一种在其他地方声明的对象,但我没有看到任何布线指向它。



另一方面,它只是有这些对象。



还有另一个,'名字' 控制器的一部分是函数的名称,我没有看到任何真正表示它的控制器,但是它在指令中以这种方式使用。



任何人都可以向我解释这个吗?我现在完全迷失了。这种不一致使得获取技术有点困难。

解决方案

有三种方法可以注释函数的依赖关系:



第一个是:显式且准确的参数名称:

  app.controller('ACtrl',函数($ scope,$ http,$ q){
//你的东西在这里
});

这意味着该函数的参数名称必须与已注册的服务/提供商的名称相匹配。 警告:如果你缩小文件(uglify,以节省空间),你将丢失参数名称,因此它将被破坏 - 将无法工作(将抱怨)。



第二个允许你选择要作为字符串文字注入的服务名称(因为字符串文字是一个值,它永远不会缩小):

  var myfunc = function($ s,$ http,$ q){
//在这里做你的东西
};
myfunc。$ inject = ['$ scope','$ http','$ q'];
app.controller('ACtrl',myfunc);

这使得Angular读取函数的$ inject属性,并且不是按名称匹配形式参数,而是通过相同数组位置的值。因此,即使您缩小文件,$ scope也将以$ s为单位。如果函数中不存在$ inject,那么你将回到第一个 - 而不是推荐 - 的情况。



第三个类似于第二个(即它将通过字符串指定依赖关系并抵制丑化):

  var myfunc = function($ s,$ http,$ q ){
//在这里做你的东西
}
app.controller('ACtrl',['$ scope','$ http','$ q',myfunc]);

请注意,数组的最后一个元素是要调用的函数。它看起来有点令人毛骨悚然,但它是一致的。 Angular这样做:如果控制器是一个数组,则弹出最后一个元素 - 它将是函数。前面的元素(剩下的数组)被威胁,就像它们是函数中的 $ inject 值一样。



控制器和提供者必须有一个名称来引用它们 - 我使用'ACtrl'作为控制器的名称。它不是函数的名称,而是在依赖注入(用于提供者)和ngRoute(用于控制器)之类的内部名称。



声明名称是您要求的接线的第一个界限。在三种形式的依赖注入中使用它们是这种布线的第二种联系。



记住 AdvancedGithubUser 是注册提供商, $ http 。唯一的区别是 $ http 内置于Angular中,而AdvancedGithubUser则不是。美元符号起始符号应该保留给Angular,但这不是一个要求 - 只是一个好习惯。 AdvancedGithubUser 已创建(在外部模块中),例如:

  app.service('AdvancedGithubUser',AdvancedGithubUser); 
//是AdvancedGithubUser构造函数。


I am new to angular.js, and went through several tutorials, including all of the ones here on codeschool. I found them very useful, and learned a lot. But now that I have finished my "introduction" and am getting into trying to use it in some things, I am finding some confusing inconsistencies, most notably, "dependency injection".

In the tutorials I took, dependencies for services were done like this;

app.controller('name', [ $http, $scope, function($http, $scope) {
   // .. code ... //
}]);

This strikes me as odd, but it works anyway. I was confused as to why the [] didn't terminate before the function (I am presuming this is what you refer to as a 'callback' function in javascript?). I was expecting it more like require.js where it would have been ...

app.controller('name', [ '$http', '$scope' ], function($http, $scope) { });

However then I began to look at examples and demos of angular online, and I found this wasn't consistent. For instance, examine the following links;

In each of these, I see dependency injection used like this;

app.controller('name', function($http, AdvancedGithubUser) { });
app.controller('name', function($scope){ });
function controllerName($scope) { };

They completely bypass the array like syntax, and all three are different. In one, it takes a type of object that is declared somewhere else, but I don't see any wiring done to point to it.

In another, it just kind of has these objects.

And still in another, the 'name' part of the controller is the name of the function, and I see nothing that really denotes it as a controller, but it is used that way in directives.

Can anyone explain this to me? I am completely lost now. This inconsistency makes it a bit difficult to pick up the techniques.

解决方案

There are THREE ways to annotate dependencies on a function:

The first one is: be explicit and exact with the parameter names:

app.controller('ACtrl', function($scope, $http, $q) {
    //your stuff here
});

This one implies that the function has param names which must match the names of services/providers already registered. Caveat: if you minify the file (uglify, to save space), you will lose the parameter names, and so it will be broken - will not work (will complain).

The second one lets you choose the service names to inject as string literals (since a string literal is a value, it is never minified):

var myfunc = function($s, $http, $q) {
    //do your stuff here
};
myfunc.$inject = ['$scope', '$http', '$q'];
app.controller('ACtrl', myfunc);

This makes Angular read the $inject property of the function, and match formal parameters not by name, but by value in the same array position. So $scope will be in $s even if you minify the file. If $inject does not exist in the function, then you're back in the first - and not recommended - case.

The third one is similar to the second (i.e. it will specify dependencies by strings and will resist the uglyfication):

var myfunc = function($s, $http, $q) {
    //do your stuff here
}
app.controller('ACtrl', ['$scope', '$http', '$q', myfunc]);

Notice that the last element of the array is the function to call. It looks a bit creepy, but it is consistent. Angular does this: If the controller is an array, the last element is popped - it will be the function. The former elements (the remaining array) are threated exactly as if they were the $inject value in the function.

Controllers and providers must have a name to reference them - I used 'ACtrl' as name of the controller. It's not the name of the function, but an internal name to use in Dependency Injection (for providers) and stuff like ngRoute (for controllers).

Declaring the name is the first bound of the wiring you are asking for. Using them in any of the three forms of Dependency Injection is the second bond of such wiring.

Remember: AdvancedGithubUser is a registered provider, as is $http. The only difference is that $http is built-in in Angular, and AdvancedGithubUser is not. Dollar-sign-starting symbols should be reserved to Angular, but it is not a requirement - just a good practice. AdvancedGithubUser was created (in an external module) with something like:

app.service('AdvancedGithubUser', AdvancedGithubUser);
//being AdvancedGithubUser a constructor.

这篇关于对AngularJS依赖注入不一致感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆