我真的需要有关使用Isolated Scope测试AngularJS指令的建议和指导。
假设我有以下指令(有效):
angular.module('myApp')
.directive('pageNav', function() {
return {
restrict: 'A',
scope: {
title: '@'
},
transclude: true,
templateUrl: 'pageNav.html',
link: function(scope, element, attrs) {
if (attrs.pageNav == 'translucent') {
element.find('nav').addClass('newClass');
}
}
};
})
;
这是模板网址代码:
<nav class="pageNav">
<div class="content">
<h1 ng-if="title">{{ title }}</h1>
<div class="contentRight" ng-transclude></div>
</div>
</nav>
现在我有以下测试
describe('Page Nav Directive', function() {
var $scope,
element;
beforeEach(module('myApp'));
beforeEach(module('pageNav.html'));
beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope;
$scope.title = "hey hey, my my";
element = angular.element('<div page-nav></div>');
// element = angular.element('<div page-nav title="hey hey, my my"></div>');
$compile(element)($scope);
$scope.$digest();
}));
it('should render the directive', function() {
// this test will fail if I un-comment the element above
expect(element.find('div').eq(1).attr('class')).toBe('contentRight');
});
it('should render a title', function() {
// this test will pass if I un-comment the element above
expect(element.find('h1').eq(0).text()).toBe('hey hey, my my');
});
})
;
现在我不明白为什么第二个测试因第一个元素而失败,即使我已设置$scope.title
(由于某种原因,未呈现绑定{{ title }}
)。现在,如果我将$scope.title
作为属性放在元素上,第二个测试将在渲染工作时通过,但第一个测试失败了吗?我甚至将第一次测试改为
expect(element.scope().find('div').eq(1).attr('class')).toBe('contentRight');
使用时我将元素$scope.title
作为属性,但这也失败了。
我发现很少或没有关于使用隔离范围测试AngularJS指令的好文档,我正在拔掉头发。我对此问题的任何指导,信息或解释都将非常感激。
答案 0 :(得分:3)
问题1:设置$scope.title
(由于某种原因,未呈现绑定{{ title }}
)
当然,因为您使用title: '@'
,@
表示您使用静态字符串进行绑定。
问题2:
您正在使用templateUrl
,浏览器必须启动 ajax请求才能加载模板,这意味着该指令的模板尚未加载在当前函数中,必须等待ajax请求才能完成=&gt;结果是不可预测的。
正如这个DEMO所示,如果我在同一个函数中立即检查已编译的html,我看到它没有被编译。为了向您展示templateUrl是正确的并且稍后会加载,我使用console.log
添加了一个DEMO并使用对象引用来证明它
如果我使用内联template
,就像在此DEMO中一样,模板会被替换(但不会被编译)。
问题3:
Angular js编译功能在当前函数中没有完成,您可能需要使用$ timeout来为下一个周期安排它。 DEMO