8

我有一个关于 AngularJs 范围的问题,尤其是可以使用 Batarang Chrome 扩展程序检查这些范围的方式。

我有以下html

<!doctype html>
<html lang="en" ng-app="myApp">
<head>
    <meta charset="utf-8">
    <title>My AngularJS App</title>
    <link rel="stylesheet" href="css/app.css"/>
</head>
<body>

<div ng-controller="myCtrl">

    <div enhanced-textarea ng-model="name"></div>
     <div cmp>
        <h3>{{name}}</h3>
        <div notice></div>
    </div>
</div>

<script src="lib/angular/angular.js"></script>
<script src="js/directives.js"></script>
<script src="js/controllers.js"></script>
<script src="js/app.js"></script>
</body>
</html>

以下是指令

'use strict';

angular.module('myApp.directives', [])
    .directive('cmp', function () {
        return {
            restrict: 'A',
            controller: 'cmpCtrl',
            replace: true,
            transclude: true,
            scope: {
                name: '='
            },
            template: '<div ng-transclude></div>'
        };
    })
    .controller('cmpCtrl', ['$scope', '$element', '$attrs' , function ($scope, $element, $attrs) {
        $scope.$parent.$watch('name', function (newVal) {
            if (newVal) {
                $scope.$parent.updatedSize = newVal.length;
            }
        }, true);
    }])
    .directive('enhancedTextarea', function () {
        return {
            restrict: 'A',
            replace: true,
            transclude: true,
            template: '<textarea ng-transclude></textarea>'
        };
    })
    .directive('notice', function () {
        return {
            restrict: 'A',
            require: '^cmp',
            replace: true,
            scope: {
                updatedSize: '='
            },
            template: '<div>{{size}}</div>',
            link: function ($scope, $element, $attrs, cmpCtrl) {
                $scope.$parent.$watch('updatedSize', function (newVal) {
                    if (newVal) {
                        $scope.size = newVal;
                    }
                }, true);
            }
        };
    });

控制器

'use strict';

angular.module('myApp.controllers', [])
  .controller('myCtrl', ['$scope', function($scope) {
        $scope.name = 'test';
  }]);

当我使用batarang检查范围时,我得出以下结论

  • 范围 002:ng-app
  • 范围 003:ng-controller (myCtrl)
  • 范围 004:????
  • 范围 005:cmpCtrl(cmp 指令的控制器)
  • 范围 006:cmp 内部(h3 和通知)
  • 范围007:通知指令的链接功能

    1. 以上是正确的吗?
    2. 另外,我最大的疑问是004范围对应什么?

完整的应用程序位于 github 上

另请参阅下面的屏幕截图:

屏幕截图

4

2 回答 2

8

并不是每个$scope都必须对应于您页面的一个元素。事实上,在每一个 AngularJS 应用程序中,都有一堆$scopes不直接链接到任何元素的。

在您的情况下,ng-transclude它会导致创建子范围。

看一下 AngularJS 的实现,它会导致你的004 $scope.

if (!transcludedScope) {
    transcludedScope = scope.$new();
    transcludedScope.$$transcluded = true;
    scopeCreated = true;
}

https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L959

如果您想自己深入挖掘,请在您的 AngularJS 文件中设置断点:

在此处输入图像描述

然后只需使用调用堆栈并跟随兔子......

于 2014-03-09T21:55:39.667 回答
2

我还使用此方案来调试和检查元素范围内的内容,这可能会有所帮助:

  • 您使用 chrome 开发工具检查元素
  • 选择某个元素后,您可以通过在控制台中输入来获取其范围:

angular.element($0).scope()

  • 您可以以相同的方式获取控制器,而不是 scope() 您可以键入 controller()

  • 为了在您的代码中设置断点并在 chrome 调试器中查看(我有时发现这比在开发工具中设置断点更容易)您可以键入:

debugger;

在您的源代码和开发工具中将停在那里,以便您看到声明的变量等。

于 2016-05-02T12:10:51.500 回答