【问题标题】:AngularJS: DOM manipulation once view is fully loadedAngularJS:视图完全加载后的 DOM 操作
【发布时间】:2014-11-13 21:59:21
【问题描述】:

为这篇长篇道歉 - 我希望它不会让太多人失望。我所拥有的是工作,但我只是不确定这是否是“正确”的做事方式,所以我只是在寻找一些建议。

我有一个页面,我在其中使用窗口大小来计算放置动态元素数量的位置。这些元素根据窗口的大小进行间隔,然后我使用 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>

我正在使用mapping-resize 指令来调整所有内容的大小,但这会在每个ng-repeat 上运行。真的,我只想运行一次,一旦创建了所有子元素,但如果我将指令放在父 div (panel_content) 上,它不知道指令运行时的子元素,所以不会t 重新定位它们。

我的指令目前是这样的:

app.directive('mappingResize', ['$timeout', function($timeout) {
    return function(scope, elem, attrs) {

        if(scope.$last) {
            $timeout(function() {
                positionElements();
            });
        }
    }
}]);

positionElements() 正如它所暗示的那样,我的所有代码都用于在创建元素后定位元素。它工作正常,尽管它可能以更“有角度的方式”完成(它只是一个依赖于成熟 jQuery 的标准 JS 函数)。

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

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

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

无论如何,对以上内容的建议或意见将不胜感激。

【问题讨论】:

    标签: javascript angularjs angularjs-directive timeout angularjs-ng-repeat


    【解决方案1】:

    使用 $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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多