简体   繁体   English

在Angular控制器的回调中,为什么必须将参数命名为“ $ scope”?

[英]In Angular controller's callback, why does parameter have to be named “$scope”?

I'm writing a simple controller in Angular, but there is something I can't figure out. 我正在用Angular写一个简单的控制器,但是有些东西我不知道。

When writing the callback function, ie the second parameter in module.controller('myController', function($scope){ 编写回调函数时,即module.controller('myController', function($scope){

I am specifying a parameter, here called $scope . 我正在指定一个参数,这里称为$scope I got this code from the Angular documentation. 我从Angular文档中获得了这段代码。

However, what's strange is that if I change $scope to something else, like abc , the controller no longer works. 但是,奇怪的是,如果我将$scope更改$scope其他内容,例如abc ,则控制器将不再起作用。

But it should, shouldn't it? 但是应该,不是吗? Isn't $scope just the name of a parameter? $scope不仅仅是参数的名称吗? For example, for a function like 例如,对于像

var func = function(abc){
    alert(abc);
}

should work even if I change the parameter to xyz , like 即使我将参数更改为xyz也应该工作

var func = function(xyz){
    alert(xyz);
}

Is something else going on here? 这里还有其他事情吗? Is the parameter $scope really referring to the global Angular object? 参数$scope真的指向全局Angular对象?

Here's my code overall 这是我的整体代码

<html ng-app="MyFirstApp">
<head>

    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <title>My Page</title>

    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>


    <script>
    var module = angular.module("MyFirstApp", []);
    module.controller('myController', function($scope){
        $scope.airports = {
            "PDX": {
                "code": "PDX",
                "name": "Portland International Airport",
                "city": "Portland",
                "destinations": [
                "LAX",
                "SFO"
                ]
            },
            "STL": {
                "code": "STL",
                "name": "Lambert-St. Louis International Airport",
                "city": "St. Louis",
                "destinations": [
                "LAX",
                "MKE"
                ]
            },
            "MCI": {
                "code": "MCI",
                "name": "Kansas City International Airport",
                "city": "Kansas City",
                "destinations": [
                "LAX",
                "DFW"
                ]
            }
        };

        var p = "pee";
        $scope.airportsArray = function arr(){
            var array = [];
            for (i in $scope.airports){
                array.push(i);
            }
            return array;
        }
    });
    </script>
</head>

<body ng-controller="myController">
    <div>
        {{ airportsArray() }}
    </div>
</body>
</html>

This mechanism is called Implicit Dependencies , It is one of the mechanism used by angularjs to determine what value to be injected to the argument. 这种机制称为隐式依赖 ,它是angularjs用于确定要向参数注入什么值的机制之一。 One mechanism is to make the determination based on the parameter name that is why you are facing the problem when you rename the argument. 一种机制是根据参数名称进行确定,这就是在重命名参数时面临问题的原因。

This can cause problems if you minify your code, since that may rename your local parameters... so there are other safe methods to inject the values 如果您压缩代码,则可能会导致问题,因为这可能会重命名您的本地参数...因此,还有其他安全的方法可以注入值

If you want to give another name for the parameter you can use a different syntax called Inline Array Annotation , in the below format the actual name of the value to be passed is passed as a string 如果要为参数指定其他名称,则可以使用称为“ 内联数组注释”的另一种语法,以以下格式将要传递的值的实际名称作为字符串传递

module.controller('myController', ['$scope', function(abc){
}])

Another option is called $inject Property Annotation 另一个选项称为$ inject属性注释

function myCtrl(abc) {}
myCtrl.$inject = ['$scope']
module.controller('myController', myCtrl)

It's because Angular uses Function#toString to get (a form of) the source code of your function as part of how it works, and it looks in that string specifically for the $scope variable in order to apply its automation of things. 这是因为Angular使用Function#toString来获取Function#toString的源代码(以其形式)作为其工作方式的一部分,并且它在字符串中专门针对$scope变量进行查找,以便对其进行自动处理。 Here's an example of Function#toString : 这是Function#toString的示例:

 function display(msg) { var p = document.createElement('p'); p.innerHTML = String(msg); // <== Implicit call to Function#toString document.body.appendChild(p); } display(display); 
 body { font-family: monospace; } 

You can see this in action in the source : 您可以在源代码中看到这一点:

/**
 * @ngdoc module
 * @name auto
 * @description
 *
 * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
 */

var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var $injectorMinErr = minErr('$injector');

function anonFn(fn) {
  // For anonymous functions, showing at the very least the function signature can help in
  // debugging.
  var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
      args = fnText.match(FN_ARGS);
  if (args) {
    return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
  }
  return 'fn';
}

function annotate(fn, strictDi, name) {
  var $inject,
      fnText,
      argDecl,
      last;

  if (typeof fn === 'function') {
    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);
        }
        fnText = fn.toString().replace(STRIP_COMMENTS, '');
        argDecl = fnText.match(FN_ARGS);
        forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
          arg.replace(FN_ARG, function(all, underscore, name) {
            $inject.push(name);
          });
        });
      }
      fn.$inject = $inject;
    }
  } else if (isArray(fn)) {
    last = fn.length - 1;
    assertArgFn(fn[last], 'fn');
    $inject = fn.slice(0, last);
  } else {
    assertArgFn(fn, 'fn', true);
  }
  return $inject;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM