[英]Why is my $watch not working in my directive test - Angularjs
I have a directive in which I pass in an attrs
and then it is watched in the directive. 我有一个指令,在该指令中我传入了
attrs
,然后在该指令中对其进行监视。 Once the attrs
is changed, then an animation takes place. 一旦更改了
attrs
,就会进行动画处理。 My attrs
always is undefined when the $watch
gets triggered. $watch
触发时,我的attrs
总是不确定的。
App.directive('resize', function($animate) {
return function(scope, element, attrs) {
scope.$watch(attrs.resize, function(newVal) {
if(newVal) {
$animate.addClass(element, 'span8');
}
});
};
});
And here is my test: 这是我的测试:
describe('resize', function() {
var element, scope;
beforeEach(inject(function($compile, $rootScope) {
var directive = angular.element('<div class="span12" resize="isHidden"></div>');
element = $compile(directive)($rootScope);
$rootScope.$digest();
scope = $rootScope;
}));
it('should change to a span8 after resize', function() {
expect($(element).hasClass('span12')).toBeTruthy();
expect($(element).hasClass('span8')).toBeFalsy();
element.attr('resize', 'true');
element.scope().$apply();
expect($(element).hasClass('span8')).toBeTruthy();
});
});
When the attrs
changes, my watchers newValue
is undefined and so nothing happens. 当
attrs
更改时,我的观察者newValue
是未定义的,因此什么也没有发生。 What do I need to do to make this work? 我需要做些什么才能使这项工作? Here is a plunker
这是一个矮人
You are not watching the value of attrs.resize
; 您没有在看
attrs.resize
的值; you are watching the value pointed by attrs.resize
instead, in the test case a scope member called isHidden
. 您正在查看
attrs.resize
指向的值,在测试用例中,一个名为isHidden
的范围成员。 This does not exist, thus the undefined
. 这不存在,因此为
undefined
。
For what you aare trying to do, the following would work: 对于您想尝试做的事情,以下方法将起作用:
App.directive('resize', function($animate) {
return function(scope, element, attrs) {
scope.$watch(
// NOTE THE DIFFERENCE HERE
function() {
return element.attr("resize");
// EDIT: Changed in favor of line above...
// return attrs.resize;
},
function(newVal) {
if(newVal) {
$animate.addClass(element, 'span8');
}
}
);
};
});
EDIT: It seems that the attrs
object does NOT get updated from DOM updates for non-interpolated values. 编辑:看来,
attrs
对象没有得到来自DOM更新更新的非插值。 So you will have to watch element.attr("resize")
. 因此,您将不得不观看
element.attr("resize")
。 I fear this is not effective though... See forked plunk: http://plnkr.co/edit/iBNpha33e2Xw8CHgWmVx?p=preview 我担心这是行不通的……请参阅叉状塞子: http ://plnkr.co/edit/iBNpha33e2Xw8CHgWmVx? p= preview
Here is how I was able to make this test work. 这就是我使这项测试起作用的方式。 I am passing in a variable as an
attr
to the directive. 我将变量作为
attr
传递给指令。 The variable name is isHidden
. 变量名称为
isHidden
。 Here is my test with the updated code that is working. 这是我对正在运行的更新代码的测试。
describe('resize', function() {
var element, scope;
beforeEach(inject(function($compile, $rootScope) {
var directive = angular.element('<div class="span12" resize="isHidden"></div>');
element = $compile(directive)($rootScope);
$rootScope.$digest();
scope = $rootScope;
}));
it('should change to a span8 after resize', function() {
expect($(element).hasClass('span12')).toBeTruthy();
expect($(element).hasClass('span8')).toBeFalsy();
element.scope().isHidden = true;
scope.$apply();
expect($(element).hasClass('span8')).toBeTruthy();
});
});
I am able to access the variable isHidden
through the scope that is attached to the element
. 我可以通过附加到
element
的作用域访问变量isHidden
。 After I change the variable, the I have to run $digest
to update and then all is golden. 更改变量后,必须运行
$digest
进行更新,然后一切正常。
I feel that I should probably be using $observe
here as was noted by package
. 我觉得我应该在这里使用
$observe
,如package
。 I will look at that and add a comment when I get it working. 我将对其进行研究,并在其起作用时添加评论。
As Nikos has pointed out the problem is that you're not watching the value of attrs.resize so what you can try doing is this: 正如Nikos指出的那样,问题在于您没有关注attrs.resize的值,因此您可以尝试执行以下操作:
Create a variable to hold your data and create these $watch functions: 创建一个变量来保存数据并创建以下$ watch函数:
var dataGetter;
scope.$watch(function () {
return attrs.resize;
}, function (newVal) {
dataGetter = $parse(newVal);
});
scope.$watch(function () {
return dataGetter && dataGetter(scope);
}, function (newVal) {
// Do stuff here
});
What should happen here is that Angular's $parse
function should evaluate attrs.resize
and return a function like this . 这里应该发生的是Angular的
$parse
函数应该评估attrs.resize
并返回类似this的函数。 Then you pass it the scope and do something. 然后,您将范围传递给它并执行某些操作。 As long as
attrs.resize
is just a boolean then newVal in the 2nd watch expression should be a boolean, I hope. 我希望,只要
attrs.resize
只是一个布尔值,那么第二个watch表达式中的newVal就应该是一个布尔值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.