Javascript 更新模板并调用$digest不会触发参数正确的$watch-单元测试angularjs
我有一个简单的指令,它根据指令的Javascript 更新模板并调用$digest不会触发参数正确的$watch-单元测试angularjs,javascript,angularjs,unit-testing,jasmine,karma-jasmine,Javascript,Angularjs,Unit Testing,Jasmine,Karma Jasmine,我有一个简单的指令,它根据指令的scope属性向元素添加或删除focus类 我想写两个测试 第一次测试验证,当scope.addFocus属性设置为'true'时,focus类是否在元素上。这个测试通过了 然后我更新指令的编译模板,将scope.addFocus属性更改为'false',触发$digest(),并期望该指令将更新元素的类并删除focus类。这个测试失败了 以下是指向plunkr的链接: 任何想法,为什么$compiledTemplate.attr('add-focus','fal
scope
属性向元素添加或删除focus
类
我想写两个测试
第一次测试验证,当scope.addFocus
属性设置为'true'
时,focus
类是否在元素上。这个测试通过了
然后我更新指令的编译模板,将scope.addFocus
属性更改为'false'
,触发$digest()
,并期望该指令将更新元素的类并删除focus
类。这个测试失败了
以下是指向plunkr的链接:
任何想法,为什么$compiledTemplate.attr('add-focus','false')$directiveScope.$digest()代码>将不会更新
是否按预期更新类
指令代码
myApp.directive('myDirective', function() {
return {
scope: {
addFocus: '@'
},
restrict: 'A',
link: function (scope, element, attr) {
scope.$watch(
function() { return scope.addFocus; },
function (newValue, oldValue) {
if (newValue === 'true') {
element.addClass('focus');
} else {
element.removeClass('focus');
}
},
false
);
}
};
});
测试
describe('myApp', function () {
var $compile, $timeout, $rootScope;
var $directiveScope;
var template = '<div my-Directive add-focus="true"></div>';
var $compiledTemplate;
beforeEach(function () {
module('myApp');
});
beforeEach(angular.mock.inject(function(_$compile_, _$timeout_, _$rootScope_) {
$compile = _$compile_;
$timeout = _$timeout_;
$rootScope = _$rootScope_;
}
));
beforeEach(function() {
$directiveScope = $rootScope.$new();
$compiledTemplate = $compile(template)($directiveScope);
$directiveScope.$digest();
});
// Test 1
it('directive is compiled and has focus class', function() {
console.log('test1', $compiledTemplate[0]);
expect($compiledTemplate.hasClass('focus')).toBe(true);
});
// Test 2
it('focus class is removed', function() {
$compiledTemplate.attr('add-focus', 'false');
$directiveScope.$digest();
$timeout(function() {
console.log('test2', $compiledTemplate[0]);
expect($compiledTemplate.hasClass('focus')).toBe(false);
}, 0);
$timeout.flush();
});
});
description('myApp',函数(){
var$compile,$timeout,$rootScope;
var$directiveScope;
var模板=“”;
var$compiledTemplate;
beforeach(函数(){
模块(“myApp”);
});
beforeach(angular.mock.inject)(函数($compile、$timeout、$rootScope){
$compile=\$compile;
$timeout=$timeout;
$rootScope=\u$rootScope;
}
));
beforeach(函数(){
$directiveScope=$rootScope.$new();
$compiledTemplate=$compile(模板)($directiveScope);
$directiveScope.$digest();
});
//测试1
它('指令已编译并具有焦点类',函数(){
log('test1',$compiledTemplate[0]);
expect($compiledTemplate.hasClass('focus')).toBe(true);
});
//测试2
它('焦点类被删除',函数(){
$compiledTemplate.attr('add-focus','false');
$directiveScope.$digest();
$timeout(函数(){
log('test2',$compiledTemplate[0]);
expect($compiledTemplate.hasClass('focus')).toBe(false);
}, 0);
$timeout.flush();
});
});
更新了
问题是观察者并没有被称为自己。我们需要使用isolateScope进行同样的操作。我创建了isolateScope,如下所示:
isolateScope = $compiledTemplate.isolateScope();
并在spec中切换addFocus值以触发观察者
isolateScope.addFocus = false;
答案已经给出并被接受,尽管这并没有什么好处:当您使用输入测试输入测试指令时,不要直接更改指令范围
最简单的例子是:
beforeEach(function() {
$upperScope = $rootScope.$new();
$upperScope.param = true;
$compiledTemplate = $compile('<div my-Directive add-focus="{{param}}"></div>')($upperScope);
$upperScope.$digest();
});
// Test 1
it('directive is compiled and has focus class', function() {
expect($compiledTemplate.hasClass('focus')).toBe(true);
});
// Test 2
it('focus class is removed', function() {
$upperScope.param = false;
$upperScope.$digest();
expect($compiledTemplate.hasClass('focus')).toBe(false);
});
beforeach(函数(){
$upperScope=$rootScope.$new();
$upperScope.param=true;
$compiledTemplate=$compile(“”)($upperScope);
$upperScope.$digest();
});
//测试1
它('指令已编译并具有焦点类',函数(){
expect($compiledTemplate.hasClass('focus')).toBe(true);
});
//测试2
它('焦点类被删除',函数(){
$upperScope.param=false;
$upperScope.$digest();
expect($compiledTemplate.hasClass('focus')).toBe(false);
});