首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在AngularJS完成HTML呈现后运行jQuery代码

在AngularJS完成HTML呈现后运行jQuery代码
EN

Stack Overflow用户
提问于 2013-06-05 17:05:00
回答 3查看 62.5K关注 0票数 69

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

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

代码语言:javascript
复制
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()函数中发生的事情:

代码语言:javascript
复制
function init(){
    alert($('#wrapper').width());
    alert($('#wrapper').height());
}

我知道一定有什么简单的办法可以解决这个问题,但我现在找不到。提前谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-06-05 17:25:32

实际上,在这种情况下,角度方法不是简单的方法,而是唯一正确的方法:)

您必须编写一条指令并附加到您想要知道其高度的元素。从控制器$broadcast一个事件,指令将捕获该事件,在那里您可以进行DOM操作。决不会在控制器中。

代码语言:javascript
复制
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);
            })
        }
    };
}]);
票数 64
EN

Stack Overflow用户

发布于 2014-04-01 19:34:53

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

在控制器中:

代码语言:javascript
复制
    ['$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);
        }

In指令

代码语言:javascript
复制
.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');
            }]


        };
    }])

这是grid指令html模板的一个片段:

代码语言:javascript
复制
 <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注入的

代码语言:javascript
复制
<run-grid list="list" selected="selectedActionID"></run-grid>
票数 5
EN

Stack Overflow用户

发布于 2015-12-30 23:31:36

我想添加另一个答案,因为前面的答案是在ngRepeat完成后运行的代码是一个角度代码,在这种情况下,上面所有的答案都给出了一个很好的简单的解决方案,有些比其他的更通用,如果它是重要的摘要生命周期阶段,你可以看看Ben Nadel关于它的博客,除了使用$parse而不是$eval。

但根据我的经验,正如OP所述,它通常在最终编译的DOM上运行一些jQuery插件或方法,在这种情况下,我发现最简单的解决方案是创建一个带有setTimeout的指令,因为setTimeout函数被推到浏览器队列的末尾,它总是在angular中完成所有事情之后,通常是ng-repeat,在它的父postLinking函数之后继续

代码语言:javascript
复制
angular.module('myApp', [])
.directive('pluginNameOrWhatever', function() {
  return function(scope, element, attrs) {        
    setTimeout(function doWork(){
      //jquery code and plugins
    }, 0);        
  };
});

对于那些想知道为什么不使用$timeout的人来说,它会导致另一个完全不必要的消化周期。

编辑:

感谢drzaus提供如何在不导致摘要http://www.codelord.net/2015/10/14/angular-nitpicking-differences-between-timeout-and-settimeout/的情况下使用$timeout的链接

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16935766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档