javascript - 在AngularJS完成呈现HTML之后,javascript运行jQuery代码

  显示原文与译文双语对照的内容
95 5

在控制器中,我使用 $http 或者 $resource 服务获得一些JSON数据。然后我在 $scope 中写这些数据,AngularJS更新页面的HTML结构。我的问题是,我需要知道列表( 我的意思是,HTML DOM元素)的新大小( 宽度和高度) 是由 Angular ng-repeat 指令填充的。因此,我必须在 Angular 完成DOM结构更新之后运行javascript代码。什么是正确的方法?我在过去的四小时里搜索过互联网,但我找不到解决问题的。

这就是我接收JSON数据的方式:

var tradesInfo = TradesInfo.get({}, function(data){
 console.log(data);
 $scope.source.profile = data.profile;
 $scope.trades = $scope.source.profile.trades;
 $scope.activetrade = $scope.trades[0];
 $scope.ready = true;
 init();//I need to call this function after update is complete
});

这就是 init() 函数中发生的事情:

function init(){
 alert($('#wrapper').width());
 alert($('#wrapper').height());
}

我知道一定有很容易解决这个问题,但我现在不能找到它。先谢谢了。

时间:原作者:0个回答

50 4

实际上在这种情况下,Angular 方法不是简单的方法,但是唯一正确的方法:

必须编写指令并附加到要知道的元素的高度。从你 $broadcast的控制器中,该指令将捕获事件,并且可以以执行DOM操作。从不在控制器中。

var tradesInfo = TradesInfo.get({}, function(data){
 console.log(data);
 $scope.source.profile = data.profile;
. . .
 $scope.$broadcast('dataloaded');
});
directive('heightStuff', ['$timeout', function ($timeout) {
 return {
 link: function ($scope, element, attrs) {
 $scope.$on('dataloaded', function () {
 $timeout(function () {//You might need this timeout to be sure its run after DOM render.
 element.width()
 element.height()
 }, 0, false);
 })
 }
 };
}]);
原作者:
130 0

olivér的回答很好,但有问题:如果忘记广播事件,则javascript将不会运行,而你的数据可能已经更改。另一种解决方案是监视作用域上的更改,例如:

var tradesInfo = TradesInfo.get({}, function(data) {
 console.log(data);
 $scope.profile = data.profile;
//...
});
directive('heightStuff', ['$timeout',
 function($timeout) {
 return {
 scope: {
 myData: '='
 },
 link: function($scope, element, attrs) {
 $scope.$watch('myData', function() {
 $timeout(function() {//You might need this timeout to be sure its run after DOM render.
 element.width()
 element.height()
 }, 0, false);
 })
 }
 };
 }
]);
<div height-stuff my-data="profile"></div>

在每次发生数据更改时,javascript函数都称为 ,而不需要自定义事件。

原作者:
106 5

另一个建议使用 JQuery 。为了在指令中生成的网格,必须对此进行处理。我想滚动到网格中的特定行。使用 $emit 从指令广播到父控制器:

microsoft Controller:

 ['$timeout',function($timeout){
...
 $scope.$on('dataloaded', function () {
 $timeout(function () {//You might need this timeout to be sure its run after DOM render.
 $scope.scrollToPosition();
 }, 0, false);
 });
 $scope.scrollToPosition = function () {
 var rowpos = $('#row_' + $scope.selectedActionID,"#runGrid").position();
 var tablepost = $('table',"#runGrid").position();
 $('#runGrid').scrollTop(rowpos.top - tablepost.top);
 }

在指令中

.directive('runGrid',['$timeout', function ($timeout) {
//This directive generates the grip of data
 return {
 restrict: 'E',//DOM Element
 scope: {//define isolated scope
 list: '=',//use the parent object
 selected:"="
 },
 templateUrl: '/CampaignFlow/StaticContent/Runs/run.grid.0.0.0.0.htm',//HTML template URL
 controller: ['$scope', function ($scope) {//the directive private controller, whith its private scope
//$scope.statusList = [{ data_1: 11, data_2: 12 }, { data_1: 21, data_2: 22 }, { data_1: 31, data_2: 32 }];
//Controller contains sort functionallity
 $scope.sort = { column: null, direction: 1 }
 $scope.column = null;
 $scope.direction ="asc";
 $scope.sortColumn = function (id) {
 if(id!=$scope.column) {
 $scope.column = id;
 $scope.direction ="asc";
 } else {
 $scope.column = null;
 }
 }
 $scope.toggleDir = function () {
 $scope.direction = ($scope.direction =="asc")?"desc" :"asc";
 }
 $scope.$emit('dataloaded');
 }]
 };
 }])

这是网格指令html模板的一个 Fragment:

 <div style="overflow-y:auto;height: 200px;" id="runGrid">
 <table class="table table-striped" style="table-layout:fixed">
 <tbody>
 <tr ng-repeat="status in list" id="row_{{status.action_id}}" ng-class="(status.action_id==selected)?'selected':''">
 <td>

列表和选定参数从使用该指令的html中注入

<run-grid list="list" selected="selectedActionID"></run-grid>
原作者:
131 0

I,因为你可以在ngRepeat博客中找到代码,除了使用 $parse 之外,你可以查看Nadel的Ben代码,而非使用

在这里,我们经常在浏览器中运行 setTimeout 插件或者方法,因为在浏览器中,我们发现最简单的解决方法是在浏览器中创建一个指令,通常是 ng-repeat,它是在客户端postLinking函数完成之后继续执行

angular.module('myApp', [])
.directive('pluginNameOrWhatever', function() {
 return function(scope, element, attrs) { 
 setTimeout(function doWork(){
//jquery code and plugins
 }, 0); 
 };
});

对于疑惑为什么不使用 $timeout,的人,它会导致另一个摘要循环,这是完全不必要的。

编辑:

对于如何使用 $timeout 而不导致摘要 http://www.codelord.net/2015/10/14/angular-nitpicking-differences-between-timeout-and-settimeout/的链接,Thanx到 drzaus 。

原作者:
...