带有包含 ng 包含的内联 TPL 的指令



我有一个带有内联模板的指令,其中包含一个 ng-include 指令元素。

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

我想我知道你在问什么,但这个问题真的可以使用一些修订,并包含一些示例代码。我将尝试回答,因为我不久前遇到了这个问题,并且花了很长时间才最终弄清楚,并且修复非常容易。

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

假设 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.

更全面的解释可以在本教程或此处看到

不过解决方案很简单,只需将您传递给$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在单元测试中工作所要做的全部工作。

最新更新