将函数传递给各种AngularJS方法的推荐方法是使用在AngularJS docs中调用的语法数组符号。
你应该这样做:
app.controller("MyCtrl", ['$scope', function($scope){
$scope.someData = "Array notation";
}]);
而不是:
app.controller("MyCtrl", function($scope){
$scope.someData = "non-array notation";
});
因为AngularJS依赖注入和缩小的工作方式。
我想知道将函数作为参数传递的第一种方法是否是JavaScript标准中提到的语法?我没有在网络上找到关于'数组符号'的任何内容。
答案 0 :(得分:1)
它只是一个带字符串和函数的数组。
关于符号本身没有什么神奇的或AngularJS。函数可以像任何其他数据类型一样是数组成员。
答案 1 :(得分:1)
这只是一个惯例 - 但它的思考得很好,因此在整个Angular中使用过。看一个函数 - 一个模块 - 只能有一个依赖(如你的例子),或者其中很多(从两个开始,右边),或者根本没有依赖。所以我们需要一些解决所有案例的解决方案。
天真的方法是将所有deps指定为函数参数(第二个示例)。现在,可以通过分析函数源代码来提取(并注入)它们。 Pro:写入的绝对最小代码(无论如何,您必须指定所有deps'名称)。缺点:1)基于反射(永远不会很快),2)在脚本缩小时中断(并且所有参数名称都被转换)。
这些缺点很糟糕,所以必须采用另一种方式。我们不想摆脱参数列表(那些deps仍然必须以某种方式在函数内解决,对吧?)。但现在很清楚,单个列表还不够 - 它必须在某个地方复制。
这就是Array - 一个有序序列的元素 - 非常方便。现在,注入器只需要分离该数组的最后一个元素以获取完整的deps列表。这些是字符串,而不是变量,所以它们不会被minifier修改。什么甚至更好,现在我们不必分析签名,因此注射器的工作速度更快。
从理论到实践:这就是在Angular 1.x DI模块中实现这两种方法的方法:
function annotate(fn, strictDi, name) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn === 'function') {
// first approach: only function is passed, we need to analyze the args list
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
if (strictDi) {
if (!isString(name) || !name) {
name = fn.name || anonFn(fn);
}
throw $injectorMinErr('strictdi',
'{0} is not using explicit annotation and cannot be invoked in strict mode', name);
}
// get rid of comments, it's possible to have those inside `()`
fnText = fn.toString().replace(STRIP_COMMENTS, '');
// extract arguments
argDecl = fnText.match(FN_ARGS);
// push those into injector
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
arg.replace(FN_ARG, function(all, underscore, name) {
$inject.push(name);
});
});
// ... and that took some time
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
// second approach: an array is passed
last = fn.length - 1;
// make sure its last element is a function
assertArgFn(fn[last], 'fn');
// use all but the last element as list of deps
$inject = fn.slice(0, last);
// ... and that's all, believe it or not!
} else {
assertArgFn(fn, 'fn', true);
}
return $inject;
}
如您所见,第一个if
分支用于旧方式 - 表示为函数参数的deps。第二个(更容易阅读和执行) - 对于放置在数组中的deps和函数(函数是最后一个元素)。