我有一個自定義指令,它使用一個屬性來指定它修改的另一個控件。單元測試訪問外部元素的角度指令
指令定義對象:
{
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