Angular完成渲染后运行jQuery [英] Run jQuery after Angular is done rendering
问题描述
我正在尝试使用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屋!