【问题标题】:Cannot get the scope os a controller in anugular.js无法在 angularjs 中获取控制器的范围
【发布时间】:2015-02-04 07:25:29
【问题描述】:

我正在尝试测试一个 javascript 文件,其中包含一个控制器和一些与之交互的 HTML DOM 元素。

被测类是:

function BaseConceptMenu(options) {
 var baseConceptMenu = new BaseMenu(options);

   //Public function -->Method under Test
   function showCodeConceptToolbar() {
    var scope = angular.element('#toolbar').scope();
    scope.$apply(function() {
        scope.toolbarController.show(baseConceptMenu.someObject);
    });
}

我试图模拟控制器并动态创建 HTML DOM 元素“工具栏”,而不是为了测试而尝试创建外部 HTML 模板。

我正在尝试在每个之前创建 div“工具栏”并模拟“CodeConceptToolbarController”控制器

beforeEach(inject(function ($rootScope, $compile) {
      elm = document.createElement('div');
      elm.id = 'toolbar';

        scope = $rootScope.$new();
        createController = function() {
            return $controller('CodeConceptToolbarController', {
                $scope: scope
            });
        };
        $compile(elm)(scope);
        scope.$digest();
    }));

但是当我尝试如下测试时

it('Test Code ConeptToolbarContoller', function() {
//   var toolbar = angular.element('#toolbar');

    document.getElementById("toolbar").scope().toolbarController = createController();
   //As of now,not doing any-idepth testing
   //Just a base test call
    var menu = new BaseConceptMenu({});
    expect(menu.show()).toBe(true);
});

我收到此错误

 TypeError: Cannot read property 'scope' of null

谁能提供一种方法来测试这个? 还是有更好的方法来测试这个? 目前我正在使用 Maven-jasmine 插件

【问题讨论】:

  • 您的 getElementById 可能没有返回任何内容。生成/编译时,您已经引用了该元素。为什么不使用该引用来获取范围?也可能是您的 angular.element.scope() 也失败了。在执行 scope() 调用之前,先对每一个进行多头处理。您的代码似乎也不是以可测试的方式编写的。考虑为工具栏使用指令。

标签: angularjs unit-testing jasmine jasmine-jquery jasmine-maven-plugin


【解决方案1】:

两个问题:

  1. 根据https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById,“getElementById 不会搜索不在文档中的元素。” $compile 不会将元素插入到 DOM 中——它只是设置适当的绑定(并做一些聪明的事情,比如处理模板字符串中的嵌套指令)。您的 getElementById 将无法找到匹配项。您需要将元素插入到 DOM 的某处。

  2. getElementById 返回一个原始的 HTML DOM 元素。要从中获取 Angular 范围,文档要求将其包装在 angular.element() 中:

    var element = document.getElementById(id);
    angular.element(element).scope()...
    

此模式将提供围绕元素的 Angular 包装器来完成其余的魔术。它全部基于 jqLit​​e,它不是 jQuery,但确实遵循许多相同的模式。对于那些习惯 jQuery 的人来说,就像写 $(element) 一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    • 2017-02-19
    • 1970-01-01
    • 2015-05-30
    • 2013-05-28
    相关资源
    最近更新 更多