我无法弄清楚为什么以下动画无法正常工作:
app.directive('openMenu', ['$animate', '$timeout', function($animate, $timeout) {
return {
link: function(scope, elem) {
elem.bind('click', function() {
if(elem.is(':animated'))
return;
$timeout(function() {
$animate.addClass(elem, 'see');
}, 0);
});
}
}
}]);
在这一部分中,动画根本不起作用(并且也没有添加类):
app.directive('openMenu', ['$animate', function($animate) {
return {
link: function(scope, elem) {
elem.bind('click', function() {
if(elem.is(':animated'))
return;
$animate.addClass(elem, 'see');
});
}
}
}]);
在第二个代码片段中,我只删除了$timeout
,即0,我尝试使用自动触发功能进行检查 - 动画仅在我使用超时时才有效。有人能解释我为什么吗?
middle {
margin-left: 0;
}
middle.see {
margin-left: 270px;
}
.middle.see-add {
-webkit-transition: margin-left 300ms;
-moz-transition: margin-left 300ms;
-ms-transition: margin-left 300ms;
-o-transition: margin-left 300ms;
transition: margin-left 300ms;
margin-left: 0;
}
.middle.see-add.see-add-active {
margin-left: 270px;
}
这是标记:
<div class="middle" open-menu></div>
答案 0 :(得分:2)
由于你的指令使用jQuery和jQuery修改DOM,我们需要告诉它有角度。为此,您需要执行$ scope。$ apply但是您会遇到错误:“摘要已在进行中”。
$ timeout内执行的代码保证您的代码将在下一个摘要周期安全执行。
0是默认值,您甚至不需要指定它。你可以简单地写:
$timeout(function() {
$animate.addClass(elem, 'see');
});
$ timeout服务只是一个方便的服务,相当于:
var timeout = setInterval(function(){
// do stuff
$scope.$apply();
}, 0);
您可以在官方文档中找到有关摘要机制的详细信息:https://docs.angularjs.org/error/$rootScope/inprog
答案 1 :(得分:2)
你的问题是你恰好处于Angular生命周期之外。您正在使用.bind
,因此只要有变更,Angular就不会收到通知。 $timeout
有效,因为它是向Angular通知外部更改的包装器之一。您也可以使用$apply
。 $timeout
和$apply
都采用将要执行的回调。回调完成后,Angular从digest
开始rootScope
。现在每个绑定都会更新,一切都应该正常工作。
scope.$apply(function() {
$animate.addClass(elem, 'see');
});
答案 2 :(得分:1)
我认为这是因为elem.bind('click')
是一个jQuery函数,它在角度摘要阶段之外运行。
这可能会起作用,而不是使用$timeout
:
scope.$apply(function() {
$animate.addClass(elem, 'see');
})'