我正在创建一个指令,以根据模型数据动态生成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 :(得分:0)
问题是.replaceWith()
删除了对原始DOM元素的引用。在测试中,elm
不再指向实际DOM中反映的内容。
为了解决这个问题,测试数据只需要包装在一个容器中:
inject(function($rootScope, $compile) {
elm = angular.element(
'<div>' +
'<my-replace some-attr="model.myVariable">' +
'</div>'
);
/* snip */
现在,直接替换元素将在测试中正确反映,更新后搜索<div>
的孩子。
这种事情是否是一种好的做法,我仍然不完全确定。