在Angular controller's回调,为什么参数必须命名为“$“范围”;

In Angular controller's callback, why does parameter have to be named "$scope"?

本文关键字:命名为 参数 范围 controller Angular 回调 为什么      更新时间:2023-09-26

我正在Angular中编写一个简单的控制器,但有些地方我无法理解。

写入回调函数时,即module.controller('myController', function($scope){ 中的第二个参数

我正在指定一个参数,这里称为$scope。我从Angular文档中得到了这段代码。

然而,奇怪的是,如果我将$scope更改为其他内容,如abc,则控制器将不再工作。

但它应该,不是吗?$scope不就是一个参数的名称吗?例如,对于这样的函数

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

即使我将参数更改为xyz,也应该工作,就像一样

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

这里还有什么事吗?参数$scope真的是指全局Angular对象吗?

这是我的代码整体

<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>

这个机制被称为隐式依赖项,它是angularjs用来确定向参数注入什么值的机制之一。一种机制是根据参数名称进行确定,这就是重命名参数时遇到问题的原因。

如果你缩小代码,这可能会导致问题,因为这可能会重命名你的本地参数。。。因此,还有其他安全的方法来注入值

如果您想为参数指定另一个名称,可以使用一种不同的语法,称为内联数组注释,在下面的格式中,要传递的值的实际名称将作为字符串传递

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

另一个选项称为$inject属性注释

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

这是因为Angular使用Function#toString来获取函数的源代码(的一种形式),作为其工作方式的一部分,并且它在该字符串中专门查找$scope变量,以便应用其自动化功能。以下是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;
}

你可以在来源中看到这一点:

/**
 * @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;
}