AngularJS:视图完全加载后的DOM操作

AngularJS: DOM manipulation once view is fully loaded

本文关键字:DOM 操作 加载 视图 AngularJS      更新时间:2023-09-26

为这篇冗长的帖子道歉-我希望它不会让太多人反感。我所做的是有效的,但我不确定这是否是"正确"的做事方式,所以我只是在寻求一些建议。

我有一个页面,在那里我使用窗口大小来计算在哪里放置动态数量的元素。这些元素是根据窗口的大小间隔开的,然后我使用Canvas元素绘制将每个元素连接到中心元素的线。

我的问题是知道什么时候所有的元素都已经创建好了,现在可以调整大小和定位了。

我的HTML是这样的:

    <div class="panel">
        <div class="panel_content">
            <div class="input_mapping" ng-repeat="input in inputs" mapping-resize>
                {{input.name}}
            </div>
        </div>
    </div>
    <div class="panel">
        <div class="panel_content">
            <div class="central_mapping">
                {{mapping.name}}
            </div>
        </div>
    </div>
    <div class="panel">
        <div class="panel_content">
            <div class="output_mapping" ng-repeat="output in outputs" mapping-resize>
                {{output.name}}
            </div>
        </div>
    </div>

我正在使用映射调整大小的指令来调整所有内容的大小,但这在每次ng重复时都会运行。实际上,我只想在创建完所有子元素后运行一次,但如果我将指令放在父div(panel_content)上,它在指令运行时不知道子元素,因此不会重新定位它们。

我的指令目前是:

app.directive('mappingResize', ['$timeout', function($timeout) {
    return function(scope, elem, attrs) {
        if(scope.$last) {
            $timeout(function() {
                positionElements();
            });
        }
    }
}]);

正如它所建议的,positionElements()是我所有代码在创建元素后用于定位元素的地方。它工作得很好,尽管它可能会以更"有角度的方式"完成(它只是一个标准的JS函数,依赖于全面的jQuery)。

在指令中,我使用$last属性,因此只有当它是ng repeat中的最后一个元素时,我才会调用positionElements(),因为我需要了解所有元素才能正确定位它们。我还使用$timeout,这样代码就可以在页面呈现后排队运行。

我的问题是,这是我能做的最好的事情吗?

目前,我调用positionElements()两次——一次用于输入映射ng repeat,一次用于输出映射。实际上,我只需要在创建完所有映射元素后调用它一次(而且只调用一次)。使用$timeout和$last也感觉不太好——感觉会有一些事件告诉我视图已经创建,但我发现的一切都是死路一条。

无论如何,我们将非常感谢您对上述内容的建议。

使用$timeout并在页面末尾移动指令:

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
  $scope.model = { items: [1,2,3,4,5] };
});
app.directive('directive', function () {
  return {
    link : function (scope, elem, attrs) {
      console.log(attrs.index);
    }
  }
});
app.directive('lastDirective', function ($timeout) {
  return {
    link : function (scope, elem, attrs) {
      $timeout(function () {
        // position elements here
        console.log(attrs.index);
      });
    }
  }
});

HTML:

  <body ng-controller="MainCtrl">
    <div ng-repeat="item in model.items" directive index="1"></div>
    <div ng-repeat="item in model.items" directive index="2"></div>
    <div last-directive index="3"></div>
  </body>

打开控制台查看指令执行顺序

http://plnkr.co/edit/Y1KIGAa7hDjY9STlmPm2?p=preview