包含ng-include的内联tpl的指令

时间:2016-01-28 21:00:16

标签: angularjs angularjs-directive karma-runner karma-jasmine angularjs-http

我有一个含有ng-include指令元素的内联模板的指令。

当karma测试我的指令并记录编译元素的结果时。 tesult包含一条ng评论说ng-include是未定义的。我做错了什么?该指令工作正常,但业力测试似乎不起作用。

1 个答案:

答案 0 :(得分:2)

我想我知道你在问什么,但问题确实可以使用一些修订,并包含一些示例代码。我试图回答是因为我在一段时间后遇到了这个问题,并且需要花很多时间来解决这个问题并且修复非常简单。

我必须做出一些假设并扩展这个问题,以便为未来的读者澄清这种情况。

假设1:您的指令在测试之外正常使用。

假设2:指令模板的根元素是ng-include的根元素。基本上,它看起来像这样:

module('myapp').directive('myDirective', function(){
    return {
      restrict: 'E',
      replace: true,
      template: '<ng-include src="myRealTemplateUrl" ></div>',
    }
});

假设3:当您创建并运行与此类似的Jasmine单元测试时,elem.html()的结果未定义:

it('Renders something cool">', function(){
    var elem = $compile('<my-directive></my-directive>')($scope);
    $scope.$digest();

    console.log('ELEM', elem.html());

    expect(elem.html()).toContain("foo);
});

有了这个问题,现在可以回答这个问题了。

ng-include使用元素转换。当传递给$compile的HTML片段的根节点使用元素转换时,Angular将该根节点转换为注释节点。然后,Angular将指令的呈现版本作为兄弟节点附加到原始根节点的正下方。因此,elem现在是一个评论节点,因此elem.html()undefined

this tutorialhere

中可以看到更全面的解释

解决方案很简单,只需将传递给$compile的任何内容包装在另一个根元素中。所以不要这样做:

// don't do this
var elem = $compile('<my-directive></my-directive>')($scope);

这样做:

// but do this
var elem = $compile('<div><my-directive></my-directive></div>')($scope);

您需要做的就是让单级测试中的顶级ng-include工作。