изолированная область директивы в unittest

У меня довольно сложная директива, а упрощенная форма ниже.

http://plnkr.co/edit/QV2QyZlknGyN3zTiv3w4?p=preview

это работает, если я удалю одноуровневые элементы: http://plnkr.co/edit/rMeCyKiMm4jPqh2NFKPf?p=preview

Когда в моем шаблоне есть другие теги html одного уровня, как в прокомментированном,

console.log(el.isolateScope()) --> undefined
console.log(el.children().scope()) --> isolated scope

Я ожидал получить изолированную область директивы через el.isolateScope(). Почему он не определен? Почему поведение отличается, если есть другие элементы (все же директива не является дочерним элементом других элементов, а родственным)

js:

var app = angular.module('plunker', []);

app.directive('myTest', function () {
    return {
        restrict: 'E',
        scope: {},
        replace: true,
        template: '<div><div>far boo</div></div>',
        link: function (scope, element, attrs, controller) {
            scope.msg = 'bar';        
        },
        controller: function($scope){
            $scope.msg = 'foo';
        }
    };
});

спецификация:

describe('myTest directive:', function () {

    var scope, compile, validHTML;

    //validHTML = '<my-test></my-test>';
    validHTML = '<script type="text/ng-template" id="directive/propTmplAdd.html"><div></div></script><my-test></my-test>';

    beforeEach(module('plunker'));

    beforeEach(inject(function($compile, $rootScope){
        scope = $rootScope.$new();
        compile = $compile;
    }));

    function create() {
        var elem, compiledElem;
        elem = angular.element(validHTML);
        compiledElem = compile(elem)(scope);
        scope.$digest();

        return compiledElem;    
    }

    it('should have a scope on root element', function () {  
        var el = create();

        console.log('isolateScope', el.isolateScope())
        console.log('ch isolateScope', el.children().scope())
        console.log('ctrl', el.controller('myTest'))


        expect(el.isolateScope()).toBeDefined();
        expect(el.isolateScope().$id).not.toEqual(scope.$id);
    });

    it('should have a populated scope', function(){
        var el = create();
        expect(el.isolateScope().msg).toBeDefined();
        expect(el.isolateScope().msg).toEqual('bar');   
    });
});

person bsr    schedule 03.05.2014    source источник


Ответы (1)


Обернутый объект jqLite, который возвращает функция create() в вашем коде, будет содержать два элемента.

el[0] будет:

<script type="text/ng-template" id="directive/propTmplAdd.html" class="ng-scope"><div></div></script>

el[1] будет:

<div class="ng-scope ng-isolate-scope"><div>far boo</div></div>

При вызове el.isolateScope() он будет вызываться для первого элемента, у которого его нет.

Вам придется либо скомпилировать элементы по-другому, либо перепаковать правильный элемент в jqLite.

Например:

it('should have a populated scope', function() {

  var elements = create();
  var element = angular.element(elements[1]);

  expect(element.isolateScope().msg).toBeDefined();
  expect(element.isolateScope().msg).toEqual('bar');
});
person tasseKATT    schedule 03.05.2014