20

我是所有 Angular World 的新手,我在管理指令时遇到了问题。

我正在开发一个使用选项卡的项目,我想扩展它的功能以在窗口大小比我所有选项卡的宽度更窄时处理溢出的选项卡,所以我需要计算元素的一些尺寸来实现这一点。选项卡是从 $scope 中的对象构建的,问题是计算尺寸的指令在视图完全编译之前运行。

Plnkr 链接: http ://plnkr.co/edit/LOT4sZsNxnfmQ8zHymvw?p=preview

我试过的:

  1. 使用 templateUrl 在指令中加载模板
  2. 使用 transclude
  3. 在 ng-repeat 中使用 $last
  4. 尝试重新排序指令并在每个选项卡中创建一个虚拟指令以触发事件

我认为有一些 AngularJs 事件或属性来处理这种情况。

请大家帮忙:)

4

4 回答 4

8

我在你的 plunker 上做了一个分支,我认为这就是你要找的东西

我将您的指令更改为此

.directive('onFinishRenderFilters', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});

然后在你的 HTML 上我添加了指令

 <li ng-repeat="tab in tabs" on-finish-render-filters>

最后一件事我把我想在重复完成后运行的代码

$scope.$on('ngRepeatFinished', function (ngRepeatFinished) {
        $scope.tabs = [{
            index: 1,
            title: "Tab 1",
            link: "/tab1/"
        },{
            index: 2,
            title: "Tab 2",
            link: "/tab2/"
        },{
            index: 3,
            title: "Tab 3",
            link: "/tab3/"
        },{
            index: 4,
            title: "Tab 4",
            link: "/tab4/"
        }];

  });

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

于 2014-04-10T03:52:17.787 回答
6

对于 ng-repeat 中使用的指令,AngularJS 似乎没有可靠的渲染后回调。[1]

也许您可以通过为特定屏幕宽度添加“响应式”溢出控制元素来解决 CSS 级别的问题。

  1. https://groups.google.com/forum/#!topic/angular/SCc45uVhTt8

更新:现在有一种使用嵌套 $timeouts 的方法。见: http: //lorenzmerdian.blogspot.de/2013/03/how-to-handle-dom-updates-in-angularjs.html

于 2013-03-04T10:15:56.697 回答
6

您可以在实际的 DOM 元素上添加监视,以了解您的 ng-repeat 何时加载到 DOM 中。

给你的 ul 一个 id,比如#tabs

$scope.$watch(
    function () { return document.getElementById('tabs').innerHTML },  
    function(newval, oldval){
        //console.log(newval, oldval);
        //do what you like
    }, true);
于 2013-07-09T15:42:15.530 回答
3

根据您的评论,您已经有了一个可行的解决方案……而且它目前是我所知道的唯一解决方案:$timeout。

问题是,你想达到什么目标?当所有渲染完成时,您需要一个回调。好的,很好,但是 Angular 怎么知道呢?在您显然正在使用 Angular 开发的现代应用程序中,重新渲染可能一直发生!从后端加载数据的地方可能会发生 js 事件,即使在初始化应用程序之后也是如此,这会导致重新渲染。用户的鼠标移动可以触发元素的重新渲染,由于 CSS 规则,这些元素甚至超出了角度范围。任何时候,都可能发生重新渲染。

那么,考虑到这些因素,angularJS 在渲染完成时可以告诉你什么?它只能告诉你,当当前的 $apply 和/或 $digest 链被处理时,浏览器事件队列现在是空的。这正是 angularJS 知道的唯一信息。为此,您使用延迟为 0 的 $timeout。

是的,你是对的,在更大的应用程序中,这可能会很棘手,以至于它不再可靠。但是在这种情况下,您应该考虑如何以另一种方式解决此问题。Fi 如果稍后发生重新渲染,则一定有原因,例如从后端加载的新数据。如果是这样,您知道何时加载数据并因此发生重新渲染,因此您确切知道何时必须更新宽度。

于 2013-05-14T08:26:53.420 回答