如何在Angular因数据更改而更新布局时调用函数

时间:2013-10-04 13:53:44

标签: angularjs

我有一个ng-repeat指令,显示一个链接列表。它工作正常,但我的代码也有一个javascript函数,根据其维度放置列表。当然,在Angular完成数据绑定和修改DOM之前,列表的维度是未知的。如果我在数据更改后立即调用该函数,则放置计算会跳过枪并将列表放置为空。一旦Angular完成修改DOM,我想激活该函数。我怎么能这样做?

修改

刚试过ngcloak作为一种可能的解决方案,遗憾的是它不起作用。阅读ngcloak的文档,我的问题不是列表闪烁,而是它被放置为好像它是空的,然后保持在那里。一旦数据绑定完成,我需要一种方法来调用我的函数。

5 个答案:

答案 0 :(得分:1)

我之前通过创建除ng-repeat之外使用的自定义指令来完成此操作。例如,

<div ng-repeat="foo in bar" myDirective>

这给你的是myDirective你可以访问指令的范围并检查ng-repeat渲染中的最后一项。例如,这就是我在ng-repeat渲染的一些元素上使用同位素jquery库所拥有的:

angular
    .module('myModule')
    .directive('myDirective', function ($timeout) {
        return {
            restrict: 'A',
            link: function postLink(scope, element, attrs) {
                if (attrs.ngRepeat && scope.$last) {
                    $timeout(function() {
                        $('#myContainer').isotope({
                           layoutMode: 'fitRows'
                        });
                    });
                }
            }
        };
    });

这与html一样使用:

<div id="myContainer" ng-repeat="foo in bar" myDirective>
    <div class="element">{{foo}}</div>
</div>

应该给你你想要的东西。

当ng-repeat完成呈现重复时,只需将$('#myContainer').isotope({})替换为您要执行的内容。

答案 1 :(得分:1)

您似乎正在使用类似masonry的库来定位元素,如果是这样,请使用angular masonry指令。有一个fork也可以消除jQuery。
但无论如何,看看它,会很有用。

  • 对于文本数据,可以使用一小段延迟,例如:

    timeout = $timeout(function layout() {
      //layout elements 
    }, 30);
    
  • 对于图片,您可以在完全加载图片之前获取尺寸,here您可以找到一个好方法。

答案 2 :(得分:1)

对于任何偶然发现此问题的人,在Angular完成更新视图后,由于数据更改(不仅在页面加载后),寻找执行函数的方法:

如果将$timeout与timeout = 0一起使用(或省略第二个参数 - 它是默认值),则代码将在下一个摘要周期中执行。

$timeout(function(){
    /// your logic here
}, 0);

在问题中描述的情况下,应该在自定义指令中调用它,如@MikeDriver所述

为什么不探测角度的当前相位?

根据另一个SO回答,Angular的作者说不应该使用$阶段 - 这是一个内部机制,并不是未来安全的。 https://stackoverflow.com/a/21611534/1578982 显然,$ timeout方式也更简单。

答案 3 :(得分:0)

我认为ngCloak正是您所寻找的。

答案 4 :(得分:0)

发生数据更改时,请使用$ timeout service在延迟后调用修饰符。如果超时不够可靠,因为你无法正确猜测时间,你可以编写一个递归函数,在100ms的短暂超时之后调用自身,以检查角度是否处于摘要或应用阶段。如果它不在摘要或应用阶段,那么您可以调用贴装修改器。