AngularJS templateUrl vs template-隔离作用域

AngularJS templateUrl vs template-隔离作用域,angularjs,angularjs-directive,angularjs-scope,angular-template,plunker,Angularjs,Angularjs Directive,Angularjs Scope,Angular Template,Plunker,我有以下指示: offerListSorters.directive('offersSorter', ['myState', '$templateCache', function (myState, $templateCache){ return { scope: {}, controller: function($scope, $element, $attrs, $transclude) { [...] }, restrict: 'E',

我有以下指示:

offerListSorters.directive('offersSorter', ['myState', '$templateCache', function (myState, $templateCache){
  return {
    scope: {},
    controller: function($scope, $element, $attrs, $transclude) {
      [...]
    },
    restrict: 'E',
    //templateUrl: 'partials/offersSorterDirective.html',
    template: $templateCache.get('partials/offersSorterDirective.html'),
    replace: true,
    transclude: true
  };
}]);

我用Karma+Jasmine来测试这个代码,它是有效的。但是现在如果我切换到templateUrl(当前已被注释掉),它将不起作用。我创建了一个示例来显示这个问题。当比较sorter和bsorter指令时,当我使用templateUrl而不是template时,似乎对已编译元素的isolateScope()调用中断。有什么想法吗?

这是最奇怪的事情,我认为这实际上是一个bug,如果你使用的是templateUrl,你就不会得到一个孤立的作用域。模板本身已正确加载,但从未加载范围。我已经完成了一些额外的日志记录,签出控制台,您将看到我的意思,
bsorter
没有获得ng隔离作用域类,并且作用域返回为未定义

编辑:


我进一步更新了plnkr,以便在调用编译函数时记录控制台消息。这几乎是我的javascript/angularJS知识的极限,但是bsorter编译函数被记录为在应该返回作用域之后被调用,这与之前调用的sorter编译函数不同。

您应该在it()函数中调用isolateScope(),而不是在beforeach()中

描述(“测试…”,函数(){
var元素,等值线;
beforeach(函数(){
模块(“myApp”);
注入(函数($rootScope,$compile){
var scope=$rootScope.$new();
element=$compile(angular.element(“”)(范围);

//isoScope=element.isolateScope();通过$compile创建指令后,必须调用$rootScope.$digest(),然后它应该可以工作(现在,您在变量parentScope上调用$digest(),它是使用$rootScope.$new()创建的新范围)

您的编辑确实有些问题。我更新了更进一步的,现在可以使用了。我使用了$timeout,这不太好。在我看来,似乎templateUrl尝试首先获取地址,如果失败,它将使用缓存。但是HTTP请求失败需要时间。通过谷歌搜索额外的信息,这似乎是一个常见的issue无法知道Angular何时完成对DOM的修改。似乎使用$timeout或$evalAsync是解决此问题的两种最常见的方法。我想现在就可以了。这在测试时是一个明确的问题。感谢后续的工作,$timeout解决方案是一个方便的技巧。
describe("Testing...", function(){
    var element, isoScope;

    beforeEach(function(){
        module("myApp");

        inject(function($rootScope, $compile){
            var scope = $rootScope.$new();
            element = $compile(angular.element("<sorter></sorter>"))(scope);
            // isoScope = element.isolateScope();  <- Move from here
            $rootScope.$digest();
        });
    });

    it("something...", function(){
        isoScope = element.isolateScope();  // <- to here
        expect(isoScope.someProp).toBe("someValue");
    });
});