In my AngularJS app, there's several points at which I want to wait for a $scope to be processed into the DOM, and then run some code on it, like a jquery fadeIn, for example.
在我的AngularJS应用程序中,有几点我想等待$ scope处理到DOM中,然后在其上运行一些代码,例如jquery fadeIn。
Is there a way to listen for a digestComplete message of some sort?
有没有办法监听某种digestComplete消息?
My current method is, immediately after setting whatever $scope variables I want rendered, use setTimeout with a delay of 0 ms, so that it will let the scope finish digesting, and then run the code, which works perfectly. Only problem is, I very occasionally see the DOM render before that setTimeout returns. I'd like a method that is guaranteed to fire after digest, and before render. Any ideas?
我当前的方法是,在设置我想要呈现的任何$ scope变量之后立即使用延迟为0 ms的setTimeout,这样它将让范围完成消化,然后运行完美的代码。唯一的问题是,我偶尔会在setTimeout返回之前看到DOM渲染。我想要一种方法,保证在摘要之后和渲染之前触发。有任何想法吗?
3 个解决方案
#1
15
In this jQuery fade-in-and-out fiddle (which I found it on the JSFiddles Examples wiki page), the author defines a "fadey" directive and performs the jQuery fadeIn (or fadeOut) in the directive's link function"
在这个jQuery淡入淡出小提琴中(我在JSFiddles Examples wiki页面上找到它),作者定义了一个“fadey”指令并在指令的link函数中执行jQuery fadeIn(或fadeOut)“
<li ng-repeat="item in items" fadey="500">
...
myApp.directive('fadey', function() {
return {
restrict: 'A',
link: function(scope, elm, attrs) {
var duration = parseInt(attrs.fadey);
if (isNaN(duration)) {
duration = 500;
}
elm = jQuery(elm); // this line is not needed if jQuery is loaded before Angular
elm.hide();
elm.fadeIn(duration)
Another possible solution is to use $evalAsync: see this comment by Miško, in which he states:
另一种可能的解决方案是使用$ evalAsync:请参阅Miško的评论,其中他说:
The asyncEval is after the DOM construction but before the browser renders. I believe that is the time you want to attach the jquery plugins. otherwise you will have flicker. if you really want to do after the browser render you can do $defer(fn, 0);
asyncEval在DOM构造之后但在浏览器呈现之前。我相信这是你想要附加jquery插件的时间。否则你会闪烁。如果你真的想在浏览器渲染后做,你可以做$ defer(fn,0);
($defer was renamed $timeout).
($ defer被重命名为$ timeout)。
However, I think using a directive (since you are manipulating the DOM) is the better approach.
但是,我认为使用指令(因为您正在操作DOM)是更好的方法。
Here's a SO post where the OP tried listening for $viewContentLoaded events on the scope (which is yet another alternative), in order to apply some jQuery functions. The suggestion/answer was again to use a directive.
这是一个SO帖子,其中OP试图在范围上监听$ viewContentLoaded事件(这是另一种选择),以便应用一些jQuery函数。建议/答案再次使用指令。
#2
3
Alternatively, this example will work the same way as an AngularJS built-in ng-show directive, except it will fade-in or fade-out based on AngularJS condition:
或者,此示例的工作方式与AngularJS内置ng-show指令的工作方式相同,不同之处在于它将基于AngularJS条件淡入或淡出:
<li ng-repeat="item in items" ng-ds-fade="{condition}">
<!-- E.g.: ng-ds-fade="items.length > 0" -->
...
myApp.directive('ngDsFade', function () {
return function(scope, element, attrs) {
element.css('display', 'none');
scope.$watch(attrs.ngDsFade, function(value) {
if (value) {
element.fadeIn(200);
} else {
element.fadeOut(100);
}
});
};
});
Source: http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri
资料来源:http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri
#3
1
If all you want is to run some jQuery stuff why not try the Angular-UI jQuery Passthrough?
如果你想要的只是运行一些jQuery的东西,为什么不尝试Angular-UI jQuery Passthrough?
#1
15
In this jQuery fade-in-and-out fiddle (which I found it on the JSFiddles Examples wiki page), the author defines a "fadey" directive and performs the jQuery fadeIn (or fadeOut) in the directive's link function"
在这个jQuery淡入淡出小提琴中(我在JSFiddles Examples wiki页面上找到它),作者定义了一个“fadey”指令并在指令的link函数中执行jQuery fadeIn(或fadeOut)“
<li ng-repeat="item in items" fadey="500">
...
myApp.directive('fadey', function() {
return {
restrict: 'A',
link: function(scope, elm, attrs) {
var duration = parseInt(attrs.fadey);
if (isNaN(duration)) {
duration = 500;
}
elm = jQuery(elm); // this line is not needed if jQuery is loaded before Angular
elm.hide();
elm.fadeIn(duration)
Another possible solution is to use $evalAsync: see this comment by Miško, in which he states:
另一种可能的解决方案是使用$ evalAsync:请参阅Miško的评论,其中他说:
The asyncEval is after the DOM construction but before the browser renders. I believe that is the time you want to attach the jquery plugins. otherwise you will have flicker. if you really want to do after the browser render you can do $defer(fn, 0);
asyncEval在DOM构造之后但在浏览器呈现之前。我相信这是你想要附加jquery插件的时间。否则你会闪烁。如果你真的想在浏览器渲染后做,你可以做$ defer(fn,0);
($defer was renamed $timeout).
($ defer被重命名为$ timeout)。
However, I think using a directive (since you are manipulating the DOM) is the better approach.
但是,我认为使用指令(因为您正在操作DOM)是更好的方法。
Here's a SO post where the OP tried listening for $viewContentLoaded events on the scope (which is yet another alternative), in order to apply some jQuery functions. The suggestion/answer was again to use a directive.
这是一个SO帖子,其中OP试图在范围上监听$ viewContentLoaded事件(这是另一种选择),以便应用一些jQuery函数。建议/答案再次使用指令。
#2
3
Alternatively, this example will work the same way as an AngularJS built-in ng-show directive, except it will fade-in or fade-out based on AngularJS condition:
或者,此示例的工作方式与AngularJS内置ng-show指令的工作方式相同,不同之处在于它将基于AngularJS条件淡入或淡出:
<li ng-repeat="item in items" ng-ds-fade="{condition}">
<!-- E.g.: ng-ds-fade="items.length > 0" -->
...
myApp.directive('ngDsFade', function () {
return function(scope, element, attrs) {
element.css('display', 'none');
scope.$watch(attrs.ngDsFade, function(value) {
if (value) {
element.fadeIn(200);
} else {
element.fadeOut(100);
}
});
};
});
Source: http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri
资料来源:http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri
#3
1
If all you want is to run some jQuery stuff why not try the Angular-UI jQuery Passthrough?
如果你想要的只是运行一些jQuery的东西,为什么不尝试Angular-UI jQuery Passthrough?