为什么这有$ rootscope.$ new()?

Exi*_*tos 13 angularjs

我正在研究如何将Jasmine与Karma一起使用.我试图将一个范围注入我的控制器,从某个地方我已经拿起这个代码......

var scope = { message: 'hello' };

beforeEach(angular.mock.module('myApp'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {

    scope = $rootScope.$new();

    $controller('myController', { $scope: scope });

}));
Run Code Online (Sandbox Code Playgroud)

问题是该范围正在被线条消灭......

scope = $rootScope.$new();
Run Code Online (Sandbox Code Playgroud)

所以我可以评论它,但我想知道这条线的用途是什么?我什么时候打电话$rootscope.$new()?我理解它与隔离有关,但我并没有真正得到它的实际应用.

更新:正如Tim指出的那样,这是一个问题,因为我已经宣布了自己的范围.所以我可以修改代码....

var scope;

beforeEach(angular.mock.module('myApp'));

beforeEach(angular.mock.inject(function ($rootScope, $controller) {

    scope = $rootScope.$new();

    scope.message = 'hello';

    $controller('myController', { $scope: scope });

}));
Run Code Online (Sandbox Code Playgroud)

这更符合预期,但我仍然想知道最好的方法是什么?什么是$rootscope.$new()连供?

eth*_*far 13

$rootScope.$new创建一个$rootScope.Scope继承自的新实例$rootScope.换句话说,它创建了一个新的子范围$rootScope.

您可能在测试中使用它(例如您发布的那个)的原因是因为您的另一种选择是使用$rootScope它自己.这样做可能会造成混乱,因为它可能会在整个地方使用.

我认为最佳做法是为每个测试用例创建(并在之后销毁)新的范围.

这是你的例子改写为我认为最佳的做法:

describe('myModule', function() {

    var $rootScope;

    beforeEach(module('myModule'));

    beforeEach(function() {
        inject(function(_$rootScope_) {
            $rootScope = _$rootScope_;
        });
    });

    describe('myController', function() {

        var $scope;

        beforeEach(function createChildScopeForTheTest() {
            $scope = $rootScope.$new();
        });

        afterEach(function disposeOfCreatedChildScope() {
            $scope.$destroy();
        });

        it('tests something', function() {
            $scope.message = 'hello';

            $controller('myController', { $scope: $scope });

            expect($scope.something).toEqual('world');
        });
    }); 
});
Run Code Online (Sandbox Code Playgroud)


Bro*_*cco 3

角度中的作用域嵌套在父子关系中,全部源自单个父级$rootScope

这就是 Angular 创建$scope注入控制器的方式,以便在您对控制器进行单元测试时创建相同的体验。

如果您在控制器中执行任何需要调用 $apply 而不是必须模拟它的操作,那么这尤其有用。