简体   繁体   中英

directive isolated scope in unittest

I have a rather complex directive, and a simplified form is below.

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

it works if I remove the sibling elements: http://plnkr.co/edit/rMeCyKiMm4jPqh2NFKPf?p=preview

When my template has other sibling html tags as in the commented one,

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

I was expecting to get the isolated directive scope through el.isolateScope(). Why is it undefined? Why the behavior is different if there are other elements (still, the directive is not a child of other elements, but sibling)

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';
        }
    };
});

spec:

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');   
    });
});

The jqLite wrapped object that the create() function in your code returns will contain two elements.

el[0] will be:

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

el[1] will be:

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

When calling el.isolateScope() it will be called on the first element, which does not have one.

You will either have to compile the elements differently or rewrap the correct element in jqLite.

For example:

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');
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM