我有一个自定义指令,它使用一个属性来指定它修改的另一个控件。单元测试访问外部元素的角度指令
指令定义对象:
{
restrict: 'E',
templateUrl: 'myTemplate.html',
scope: {
targetId: '@'
},
controller: MyController,
controllerAs: 'vm',
bindToController: true
}
指令的控制器上的函数修改目标元素的内容(输入字段):
function onSelection (value) {
var $element = $('#' + vm.targetId);
$element.val('calculated stuff');
$element.trigger('input');
}
单元测试(茉莉花/噶/ PhantomJS )当前将该元素附加到页面上。这工作,但它似乎是一种代码味道。
beforeEach(inject(function($rootScope, $compile) {
var elementHtml = '<my-directive target-id="bar"></my-directive>' +
'<input type="text" id="bar">';
scope = $rootScope.$new();
angularElement = angular.element(elementHtml);
angularElement.appendTo(document.body); // HELP ME KILL THIS!
element = $compile(angularElement)(scope);
scope.$digest();
}));
afterEach(function() {
angularElement.remove(); // HELP ME KILL THIS!
});
我试着重写控制器函数以避免jQuery;这没有帮助。
如何修改指令或测试以消除appendTo/remove?
它是更大的代码气味,你在你的指令中使用id。这是非常jQuery的风格,而不是“角度的方式”。考虑在DOM树的同一分支上使用'require',或者“common-parent”或“global service”接近其他的方法(如果你不知道如何去做,那么你可以搜索或提出另一个问题 - 解释是绝对的这个问题的范围) –
@ValentynShybanov我接受修改指令的解决方案。该指令的实际用途是在输入或textarea字段中插入邮件合并占位符(不应该是指令模板的一部分,我宁愿避免跨越)。如果你想发布一个你推荐的方法或链接的例子,我会考虑接受这个答案。 – TrueWill
我不认为你可以在不重构onSelection()函数的情况下杀死代码中的add/remove元素。是否有任何理由不能将'ng-model'绑定到#bar输入中?如果你能做到这一点,那么你可以在控制器中设置值,而无需使用jQuery获取元素。 – jperezov