我经历了this Angular tutorial,并注意到变量似乎可以根据需要自由添加到函数中。我想到了这一点,只有惯例,但我错了吗?考虑最后一个文件:
app.controller('PostsCtrl', function ($scope, $location, Post) {
$scope.posts = Post.all;
$scope.post = {url: 'http://'};
$scope.submitPost = function () {
Post.create($scope.post).then(function (ref) {
$location.path('/posts/' + ref.name());
});
};
这里" $ location"被添加到$ scope和Post之间的function()。 $ location是匿名函数中2-nd参数的唯一选项,这里有3个参数,或者以某种方式查看第二个参数的名称并推断它需要在那里注入$ location?在文档中我可以看到此函数的1,2,3等参数版本的所有约定?
此代码似乎无法正常工作。帖子未定义。
答案 0 :(得分:4)
使用angular,名称 显着;在普通的JavaScript中,不是真的。
然而,如果您希望它们在上面的示例中无关紧要,您可以这样做:
app.controller('PostsCtrl', ['$scope','$location', 'Post',
function (foo, bar, foobar) {
....
}
]);
在这种情况下,您将第一,第二和第三个参数分别映射到$scope
,$location
和Post
。这实际上是一种更好的方法,当你用angular缩小时, 将改变这些参数的名称, 将打破它。
答案 1 :(得分:2)
在这种情况下,您可以按照自己的喜好订购这些参数。 Angular使用依赖注入为控制器提供依赖关系。在这种情况下,它会根据名称推断出这些依赖关系,因此您可以根据自己的喜好对它们进行排序。
不幸的是,使用这种缩小方法是不可能的。在这种情况下,您需要指定依赖项。然后,您的控制器功能必须按照定义它们的顺序进行:
app.controller('PostsCtrl',
['$scope','$location','Post', function($scope, $location, Post) {
}]);
答案 2 :(得分:1)
啊,我最初也对此感到困惑。 Angular有一个很好的功能叫Dependency Injection。这些名称很重要,因为angular会查看参数的名称并决定传递给函数的对象。在JavaScript中这种罕见的情况下,名称很重要但订单却没有。
答案 3 :(得分:1)
这里的答案确实是Angular特有的。您想在此处阅读有关依赖注入的内容:
https://docs.angularjs.org/guide/di
Implicit Dependencies部分应该是很好的阅读。简而言之,这个名称对Angular很重要,但顺序却没有。但是,原始JavaScript不是这种情况。
来自Angular网站:
使用服务名称信息注释代码有三种等效方法:
隐含地来自函数参数名称
使用$ inject属性注释
使用内联数组注释
答案 4 :(得分:1)
由于您已经有了Angular特定指令的其他答案,我将尝试用简单的代码解释Angular如何在JavaScript中实现依赖注入以及如何在普通JS中执行类似的操作。
首先,它将函数转换为字符串,然后读取参数,并从依赖项容器中提取属性,最后使用提取的参数调用该函数。这是一个如何做到这一点的非常简单的例子:
// parses function and extracts params
function di(app, f) {
var args = f.toString()
.match(/function\s+\w+\s*?\((.*?)\)/)[1] // weak regex...
.split(/\s*,\s*/)
.map(function(x){return app[x.replace(/^\$/,'')]})
return function() {
return f.apply(this, args)
}
}
// Example
// A dependency container
var app = {
foo: 'this is foo',
baz: 'this is baz'
}
// this is like adding a function with the Angular ecosystem
// the order of arguments doesn't matter
var test = di(app, function test($foo, $baz) {
console.log($foo) //=> this is foo
console.log($baz) //=> this is baz
})
// No need to pass arguments, they were injected
test()
//$ this is foo
//$ this is baz
但是通过字符串化处理DI有缺点;旧浏览器不能很好地支持Function.prototype.toString
,而缩小器会缩短变量名称,使得这种技术无用。但Angular可以通过注入与这些字符串匹配的字符串和参数来解决这个问题; minifiers不会触及琴弦。
显然AngularJS做的不仅仅是这个,但希望它会清除你的想法,这怎么可能呢?!" - 嗯,这是一种黑客行为。