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

时间:2014-05-07 14:18:16

标签: 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 });

}));

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

scope = $rootScope.$new();

所以我可以发表评论,但我想知道这条线的用途是什么?我什么时候打电话给$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 });

}));

这更像预期,但我仍然想知道最好的方法是什么?什么是$rootscope.$new()甚至是?

2 个答案:

答案 0 :(得分:12)

$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');
        });
    }); 
});

答案 1 :(得分:3)

angular中的范围嵌套在父子关系中,所有范围都来自单个父$rootScope

这是角度创建注入控制器的$scope的方式,因此当您对控制器进行单元测试时,它会创建相同的体验。

如果您在控制器中执行任何需要您调用$ apply的内容而不是必须模拟它,这将非常有用。