3

我正在尝试测试使用 templateURL 的 angularJS 指令。在我的一生中,我无法让编译器实际加载 templateURL,即使它已被放入 templateCache。我意识到 karma 会预处理所有模板内容并为每个预加载 templateCache 的模块创建模块,但我希望这将是等效的。

这是一个http://jsfiddle.net/devshorts/cxN22/2/,它演示了发生了什么。

angular.module("app", [])
.directive("test", function(){
    return {
        templateUrl:"some.html",
        replace:true
    }
});

//--- SPECS -------------------------

describe("template url test", function() {
    var element,  scope, manualCompiledElement;

    beforeEach(module('app'));

    beforeEach(inject(function($rootScope, $controller, $compile, $templateCache){
        $templateCache.put("some.html", "<div>hello</div>");

        scope = $rootScope.$new();

        element = $compile(angular.element('<test></test>'))(scope);

        manualCompiledElement = $compile(angular.element($templateCache.get('some.html')))(scope);

        scope.$digest();        
    }));

    it("has hello", function() {
        expect(element.text()).toContain('hello');
    });

    it("template cache has contents", function(){
        expect(manualCompiledElement.text()).toContain('hello');
    });       
});

我错过了什么?

4

2 回答 2

2

我意识到您不再需要知道,但在我看来,有两个问题导致了这一点。

第一个是@Words-Like-Jared 指出的。您将指令定义为仅限于属性(默认),但将其用作元素。所以你需要restrict: 'E'.

第二个问题是您的模板从未真正被检索到,并且您的编译/链接永远不会完成。指令中对模板内容的请求是异步的,因此需要根范围的摘要来解析承诺并返回它们,类似于另一个问题的答案

当您执行手动编译时,结果不是异步的,并且会立即检索模板。实际上,手动编译中的编译并没有做很多事情,因为您正在编译模板的内容,模板中没有任何指令。

beforeEach现在在你使用的地方的末尾

$scope.$digest()

您正在消化当前范围及其子范围。当您使用$rootScope.$digest()or$scope.$apply()您将在所有范围内执行摘要。所以把它改成

$rootScope.$digest()
// or
$scope.$root.$digest()

在编译后的行中意味着您的两个测试现在都将通过。我在这里更新了小提琴。

于 2013-11-02T16:57:14.870 回答
1

这是咖啡脚本中解决方案的变体

expect = chai.expect;
app = angular.module('TM_App')

app.directive "test", ()->
  templateUrl:"some.html",
  replace    :true


describe '|  testing | templateUrl',->
  element = null

  beforeEach ->
    module('TM_App')

  beforeEach ->
    inject ($compile,$rootScope, $templateCache)->
      $templateCache.put "some.html", "<div>hello {{name}}</div>"
      scope       = $rootScope.$new();
      element     = $compile('<test/>')(scope);
      scope.name = 'John'
      scope.$digest()

  it "has hello", ()->
    expect(element.text()      ).to.equal 'hello John'
    expect(element[0].outerHTML).to.equal '<div class="ng-binding">hello John</div>'
于 2015-07-28T16:42:09.547 回答