我有一个指令,我在其中传递attrs
然后在指令中观察它。更改attrs
后,就会发生动画。当attrs
被触发时,我的$watch
始终未定义。
App.directive('resize', function($animate) {
return function(scope, element, attrs) {
scope.$watch(attrs.resize, function(newVal) {
if(newVal) {
$animate.addClass(element, 'span8');
}
});
};
});
这是我的测试:
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();
});
});
当attrs
发生变化时,我的观察者newValue
未定义,因此没有任何反应。我需要做些什么来完成这项工作?这是plunker
答案 0 :(得分:1)
你没有看到attrs.resize
的价值;您正在观察 attrs.resize
所指向的值,而在测试用例中则是一个名为isHidden
的范围成员。这不存在,因此undefined
。
对于您尝试做的事情,以下方法可行:
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');
}
}
);
};
});
编辑:似乎attrs
对象 NOT 从DOM更新中获取非内插值的更新。所以你必须看element.attr("resize")
。我担心这不会有效...参见forked plunk:http://plnkr.co/edit/iBNpha33e2Xw8CHgWmVx?p=preview
答案 1 :(得分:0)
以下是我能够进行此测试的方法。我将变量作为attr
传递给指令。变量名称为isHidden
。这是我的测试,其中包含正在运行的更新代码。
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();
});
});
我可以通过附加到isHidden
的范围访问变量element
。更改变量后,我必须运行$digest
进行更新,然后全部变为黄金。
我觉得我应该像$observe
所指出的那样使用package
。我会看一下,并在我开始工作时添加评论。
答案 2 :(得分:0)
正如Nikos所指出的那样,问题在于你没有注意到attrs.resize的价值,所以你可以尝试这样做:
创建一个变量来保存数据并创建这些$ 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
});
这里应该发生的是Angular的$parse
函数应该评估attrs.resize
并返回类似this的函数。然后你将范围传递给它并做一些事情。只要attrs.resize
只是一个布尔值,那么第二个监视表达式中的newVal应该是一个布尔值,我希望。