【问题标题】:How to test $element in AngularJS controller using Karma?如何使用 Karma 在 AngularJS 控制器中测试 $element?
【发布时间】:2015-07-09 00:37:51
【问题描述】:

我遇到的问题是我的应用中有一个控制器,我使用的类似 <div ng-controller='LogbookEditCtrl'> </div> 并且这个控制器中有一个 $element 提供程序,我需要修改该元素。

describe('LogbookEditCtrl', function(){
  'use strict';

  beforeEach(module('logbooks.edit'));


  it('should create "logbook" model', inject(function($controller) {
    var scope = {},

    // THIS EXPLODES BECAUSE IT SAYS THE $element PROVIDER WAS NOT FOUND, because there
    // is no html element of course..the controller is being created on its own.
    ctrl = $controller('LogbookEditCtrl', {$scope: scope});

  }));

});

我尝试了类似以下的方法,但它再次说找不到 $element 提供程序:

beforeEach(inject(function(_$element_) {
  var element = compile('<div></div>');
  $element = element;
}));

【问题讨论】:

  • 您是否在测试中包含了 elementprovider .js 文件?即使你嘲笑它,它也需要包含在内。
  • 您收到的确切错误信息是什么?
  • 错误是:错误:未知提供者:elementProvider
  • 你所说的 elementprovider.js 是什么意思?我没遇到过,不知道你的意思。

标签: javascript angularjs unit-testing jasmine


【解决方案1】:

您需要传递该依赖项本身,因为它引用控制器的绑定元素。并且在 Angular 中没有可用的 $element 提供程序(与 $scope 非常相似,因为这些是应用程序注入器提供的动态特殊依赖项)。您可以使用 angular.element 创建一个元素对象,并将其作为局部变量传递给控制器​​构造函数,就像这样。

var scope = {}, 
    element = angular.element('<div></div>'); //provide element you want to test

ctrl = $controller('LogbookEditCtrl', {$scope: scope, $element:element });

这揭示了为什么不建议在控制器内部使用$element 并在其中执行任何 DOM 操作的事实。

【讨论】:

  • "这揭示了为什么不建议在控制器中使用 $element 并在其中执行任何 DOM 操作的事实。"这不再有效。显然要避免直接的 DOM 操作,但是当遵循组件架构时,你真的没有其他选择……至少没有更好的选择。
  • @MikeHaas 恕我直言,它仍然有效。特别是如果遵循正确的组件模式和实践,您在大多数地方都不需要这样做,但显然可能会有一些例外。如果您需要 DOM 操作,请改用指令。当今世界这两种糖都有用处,doc as well 中也明确提到了这一点,请阅读第一部分本身。
  • 您是对的,有时可能仍然需要常规指令,否则您就错了。我可以指出你源源不断,但没有时间,所以我会留下一些信息。再次从 Angular 文档中阅读该页面,并注意对 DOM 的提及。请注意如何使用生命周期挂钩以简洁的方式修改 DOM?为什么你认为 $element 之类的东西被创建为可注射的?这样就可以从控制器本身操作 DOM。甚至 angular core 也有执行此操作的指令。
  • @MikeHaas 如果我有时间看的话,你可以给我看“代码之后的代码”:) 但这并不意味着什么是对的或什么是错的。这是一个固执己见的框架,因此你有能力做很多事情,并不总是意味着你要一直做下去。 :) 根据我的经验,我编写了组件、指令等,而且我很少需要将组件控制器中的组件行为逻辑与 DOM 特定行为混合在一起,因为我倾向于尽可能地遵循 SRP,如果我需要执行一些操作的话自定义 DOM 的东西。
  • 基于您的评论“显然避免直接 DOM 操作,但在遵循组件架构时,您实际上没有其他选择”--> 很明显,您可能在组件架构和直接 DOM 访问,使用 ng/react 或任何框架的组件架构不需要您直接访问和操作 DOM,它们通过数据绑定等为您提供对 DOM 的抽象。我休息一下! :)
猜你喜欢
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多