2014-01-22 99 views
0

我正在創建一個指令,以根據模型數據動態生成DOM元素。雖然我可以正常工作,但我正在準確測試通過Jasmine替換根節點元素的問題。測試指令中的替換元素

我現在可以通過簡單地插入新節點作爲子節點並離開父元素來解決此問題。理想情況下,我想完全替換它。

我知道指令replace: true選項,但是,我需要該模板才能訪問範圍數據,以確定將生成的元素。

下面是一個簡單的指令示例和測試代碼。測試將失敗,但實際上在客戶端上正常工作。有沒有人有任何想法或建議?

是否有更好的方法來生成從範圍數據生成的元素?

指令

'use strict'; 

angular.module('myApp', [ ]) 
.directive('myReplace', function($compile) { 
    var postLink, preLink; 

    postLink = function(scope, element) { 
    /** 
    * I need to do the replacement here because the generated 
    * element needs access to the scope. 
    */ 
    var newEle; 
    element.html(
     '<p> 
     I am the replacement. I want to 
     access a scope variable: '+scope.model.myVariable+' 
     </p>'); 
    newEle = $compile(element.contents())(scope) 
    element.replaceWith(newEle); 
    }; 

    return { 
    restrict: 'E', 
    scope: { 
     myVariable: '=someAttr' 
    }, 
    link: postLink 
    }; 
}); 

* 失敗的測試*

describe('my-replace', function() { 
    var elm, scope, model, refreshElement, firstChild; 

    firstChild = function(rootEle) { 
    return angular.element(rootEle.children()[0]); 
    }; 

    beforeEach(module('MyApp')); 

    beforeEach(function() { 
    model = { 
     myVariable: 'foobar' 
    }; 

    inject(function($rootScope, $compile) { 
     elm = angular.element(
     '<my-replace some-attr="model.myVariable">' 
    ); 

     scope = $rootScope.$new(); 
     scope.model = model; 
     $compile(elm)(scope); 
     scope.$digest(); 
    }); 
    }); 

    it('replaces root element', function() { 
    /** 
    * This fails here, but it will work when run in a browser 
    */ 
    expect(elm.prop('tagName')).toBe('P'); 
    }); 
}); 

回答

0

的問題是,.replaceWith()滴參照原來的DOM元素。在測試中,elm不再指向實際DOM中反映的內容。

爲了解決這個問題,只需要對測試數據的容器被包裹:

inject(function($rootScope, $compile) { 
    elm = angular.element(
    '<div>' + 
    '<my-replace some-attr="model.myVariable">' + 
    '</div>' 
); 
/* snip */ 

現在,直接替換元素將在測試中正確反映,更新時要搜索的孩子<div>

無論這種事情是否是一種好的做法,我仍然不完全確定。