AngularJS: Fire an event immediately after $scope.

2020-05-23 04:58发布

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.

Is there a way to listen for a digestComplete message of some sort?

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?

3条回答
贪生不怕死
2楼-- · 2020-05-23 05:24

If all you want is to run some jQuery stuff why not try the Angular-UI jQuery Passthrough?

查看更多
三岁会撩人
3楼-- · 2020-05-23 05:32

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"

<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:

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);

($defer was renamed $timeout).

However, I think using a directive (since you are manipulating the DOM) is the better approach.

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.

查看更多
太酷不给撩
4楼-- · 2020-05-23 05:42

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:

<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

查看更多
登录 后发表回答