在Angular完成渲染后运行jQuery

Bha*_*lli 6 jquery angularjs

我正在尝试使用angularjs中的json对象填充配置文件页面.我正在使用指令.我有一个profile指令,它有profile-section指令作为子节点.配置文件部分具有作为子项的配置文件子部分指令.我需要在角度开始编译之前和角度完成渲染模板之后运行一个片段.

我试过了

app.run()
$timeout
$evalAsync
$(document).ready()
$scope.$broadcast
postLink function
Run Code Online (Sandbox Code Playgroud)

这是我的代码的骨架

    var app = angular.module("profile",[]);

app.controller("profileController",['$scope',function($scope){
    var ctrl = this;


}])

.controller("profileSectionController",['$scope',function($scope){
    //$scope.$emit('dataloaded');

}])


.directive("profile",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        templateUrl:'/sstatic/angular_templates/de/profile.html',
        scope:{
            person:"="
        },
        controller:'profileController',
        compile:function(elem,attrs,transclude){
            return {
                pre : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);
                //$(elem).css({"display":"none"});

                },
                post : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);
                    //$(elem).css({"display":"block"});



                }
            }
        }
    }
}])
.directive("profileSection",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        require:'^profile',
        templateUrl:'/sstatic/angular_templates/de/profile-section.html',
        scope:{
            title:"@",
            right:"=",
            sub:"="
        },
        controller:"profileSectionController",
        compile:function(elem,attrs,transclude){
            return {
                pre : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);

                },
                post : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);


                }
            }
        }
    }
}])
    .directive("profileSub",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        require:'^profile',
        templateUrl:'/sstatic/angular_templates/de/profile-sub-section.html',
        scope:{
            subsection:"="
        },
        controller:function(){

        },
        compile:function(elem,attrs,transclude){
            return function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);


                }
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)

但是,大多数它们在加载profile指令后触发,但在其子节点加载后不会触发.我无法将它附在孩子身上,因为它会发射太多次.

这是事件的预期时间表.

Start Render Event Fires
Profile Linked 
Profile Section 1 Linked
Profile Sub Section 1 Linked
Profile Sub Section 2 Linked
Profile Section 2 Linked 
Profile Sub Section 1 Linked
Profile Sub Section 2 Linked
Profile Sub Section 3 Linked
....
End Render Event Fires
Run Code Online (Sandbox Code Playgroud)

这就是现在的情况.

Start Render Event Fires
Profile Linked 
End Render Event Fires
Profile Section 1 Linked
Profile Sub Section 1 Linked
Profile Sub Section 2 Linked
Profile Section 2 Linked 
Profile Sub Section 1 Linked
Profile Sub Section 2 Linked
Profile Sub Section 3 Linked
....
Run Code Online (Sandbox Code Playgroud)

在角度的每个部分完成加载到DOM之后,我需要一些运行脚本的方法.

请帮忙.非常感激.

pix*_*its 21

在编译之前

app.run(function() {
  ...
});
Run Code Online (Sandbox Code Playgroud)

在链接之前编译之后

app.controller('ctrl', function($scope) {
   ...
});
Run Code Online (Sandbox Code Playgroud)

在渲染之前链接之后

app.directive('body', function() {
    return {
       restrict: 'E',
       link: function(scope, element, attr) {
          ... 
       }
    }
});
Run Code Online (Sandbox Code Playgroud)

渲染后

app.directive('directive', function($timeout) {
    return {
       link: function(scope, element, attr) {
          $timeout(function() {
             ...
          });
       }
    }
});
Run Code Online (Sandbox Code Playgroud)


Bha*_*lli 1

首先,非常感谢@pixelbits。

我了解指令加载的工作原理。根据 Pixelbits 的回答,我所做的是,

  • 当孙子小节加载时,我通过发出事件告诉配置文件指令,一个新的小节已到达页面。
  • 渲染该小节后,我使用 $timeout 发出另一个事件来告诉配置文件指令该小节已渲染。

由于编译发生在渲染之前,因此我可以检查配置文件指令中的 renderCount,当它等于 childCount 时,我可以确定每个孙子都已渲染。这是我触发我需要的 jquery 代码的时候。

最后的片段

var app = angular.module("profile",[]);

app.controller("profileController",['$scope',function($scope){
    var ctrl = this;


}])

.controller("profileSectionController",['$scope',function($scope){


}])
.controller("profileSubSectionController",['$scope',function($scope){
        //I emit an event telling the parent Profile directive to tell that a new sub section is in the page.
        $scope.$emit("compiled");
    }])

.directive("profile",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        templateUrl:'/sstatic/angular_templates/de/profile.html',
        scope:{
            person:"="
        },
        controller:'profileController',
        compile:function(elem,attrs,transclude){
            return {
                pre : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);
                  //this runs before everything in this chain
                  $(elem).css({"display":"none"});

                },
                post : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);




                      //I count the profileSubSection children here
                       var childCount = 0;
                        scope.$on("compiled",function(msg){
                            childCount++;
                            console.log(childCount);
                        });


                        //I check if all the profile subsections have rendered. If yes I run the script.
                        var renderedCount = 0;
                        scope.$on("rendered",function(msg){
                            renderedCount++;
                            if(renderedCount<childCount){

                            }else{
                                //this runs after everything
                                console.log("now showing profile");
                                $(".loading").hide();
                                $(elem).css({"display":"block"});
                            }

                        });


                }
            }
        }
    }
}])
.directive("profileSection",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        require:'^profile',
        templateUrl:'/sstatic/angular_templates/de/profile-section.html',
        scope:{
            title:"@",
            right:"=",
            sub:"="
        },
        controller:"profileSectionController",
        compile:function(elem,attrs,transclude){
            return {
                pre : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);

                },
                post : function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);


                }
            }
        }
    }
}])
    .directive("profileSub",[function(){
    return {
        transclude:true,
        restrict:'EA',
        replace:true,
        require:'^profile',
        templateUrl:'/sstatic/angular_templates/de/profile-sub-section.html',
        scope:{
            subsection:"="
        },
        controller:"profileSubSectionController",
        compile:function(elem,attrs,transclude){
            return function link(scope,elem,attrs,ctrl){
                    //angular.element(elem).find(".candidate-name").append(scope.person.name);
                       $timeout(function(){
                            console.log("subsection loaded");
                             //Now the sub section emits another event saying that it has been rendered. 
                            scope.$emit("rendered");
                        });



                }
        }
    }
}])
Run Code Online (Sandbox Code Playgroud)