Angular完成渲染后运行jQuery [英] Run jQuery after Angular is done rendering

查看:76
本文介绍了Angular完成渲染后运行jQuery的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用angularjs中的json对象填充个人资料页面.我为此使用指令.我有一个配置文件指令,该配置文件指令将profile-section指令作为子级.概要文件部分具有作为子项的概要文件子节指令.我需要在angular开始编译之前和angular渲染完模板之后运行一个代码段.

I am trying to populate a profile page with a json object in angularjs. I am using directives for this. I have a profile directive which has profile-section directives as children. Profile section has profile sub-section directives as children. I need to run a snippet just before angular has started compiling and just after angular has finished rendering the template.

我尝试了

app.run()
$timeout
$evalAsync
$(document).ready()
$scope.$broadcast
postLink function

这是我代码的骨架

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


                }
        }
    }
}])

但是,大多数配置文件指令加载后会触发,但子级指令加载后不会触发.我无法将其附着在孩子身上,因为它会开火太多次.

However, most of them fire after profile directive is loaded, but not after its children have loaded. I cannot attach it to the children because, it will fire too many times.

这是事件的预期时间表.

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

这就是现在的情况.

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

在角度的每个部分都加载到DOM中之后,我需要某种方式来运行脚本.

I need some way of running a script after every single part of angular is done loading in the DOM.

请帮助.非常感谢.

推荐答案

首先,非常感谢@pixelbits.

First of all, Many thanks to @pixelbits.

我了解了指令加载的工作方式.根据pixelbits的回答,我做了

I understood how directive loading works. Based on pixelbits' answer what I did was,

  • 加载子孙子节时,我会告诉配置文件指令" 通过发射事件,新的小节已进入 页.
  • 该小节呈现后,我使用$ timeout发出另一个 事件,以告知配置文件指令此小节已呈现.
  • When a grand-child subsection loads I tell the Profile Directive through an emit event, that a new subsection has arrived into the page.
  • After the subsection has rendered, I use $timeout to emit another event to tell the Profile Directive that this subsection was rendered.

由于编译是在渲染之前进行的,因此我可以检查renderCount 在配置文件指令中,当它等于childCount时,我可以 确保每个大孩子都做出了回报.这是当我触发 我需要的jQuery代码.

Since compiling occurs before rendering, I can check the renderedCount in the Profile Directive and when it equals the childCount, I can be sure that every grand child has rendered. This is when I trigger the jquery code I need.

最终摘要

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



                }
        }
    }
}])

这篇关于Angular完成渲染后运行jQuery的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆