转到过滤后的 ng-repeat 元素的位置 [英] Going to the position of a filtered ng-repeat element

查看:20
本文介绍了转到过滤后的 ng-repeat 元素的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于范围内布尔变量过滤的 ng-repeat 元素列表.

HTML:

<button ng-click="toggleSection(1)">Section 1</button><button ng-click="toggleSection(2)">Section 2</button><button ng-click="toggleSection(3)">Section 3</button><div id="$index" ng-repeat="section in section track by $index | filterSections">...

过滤器:

myApp.filter('filterSections', function() {返回函数(输入){var returnArray = [];$.each(input, function(index, bool) {if (bool) returnArray.push(bool);});返回返回数组;}})

在我的控制器中:

$scope.sections = [假,假,假];$scope.toggleSection = 函数(n){$scope.sections[n] = $scope.sections[n] ?假:真;}

但是,我希望相同的 toggleSection 函数转到它显示的元素的位置,例如...

$scope.toggleSection = function(n) {$scope.sections[n] = $scope.sections[n] ?假:真;window.scrollTo($("#" + n).position().top, 0);}

但是我不能这样做,因为 DOM 需要时间来显示它正在创建的部分.在此之前,该元素(及其位置)不存在.

设置超时可能会起作用,但这似乎很草率.

我怀疑我需要创建某种回调或承诺.是吗?

解决方案

自定义指令、promise 或其他任何东西,如果您的操作(滚动)依赖于 DOM(并且确实如此),则您无法避免在 angular 之后执行它消化循环.

因此,做到这一点的简短方法确实是超时:

$scope.toggleSection = function(n) {$scope.sections[n] = $scope.sections[n] ?假:真;$超时(功能(){window.scrollTo($("#" + n).position().top, 0);}, 0, 假);}

注意 $timeout 的第三个参数为 false:这是因为在超时执行其后,您不需要 $apply 范围(运行另一个摘要循环)回调,因为它只是 jQuery.

同样,在 DOM 更新之前滚动对浏览器来说没有意义,所以你无法避免它(但你可以隐藏它).

I have a list of ng-repeat elements that are filtered based on boolean vars in scope.

HTML:

<button ng-click="toggleSection(1)">Section 1</button>
<button ng-click="toggleSection(2)">Section 2</button>
<button ng-click="toggleSection(3)">Section 3</button>
<div id="$index" ng-repeat="section in sections track by $index | filterSections">
    ...
</div>

the filter:

myApp.filter('filterSections', function() {
    return function(input) {
        var returnArray = [];
        $.each(input, function(index, bool) {
            if (bool) returnArray.push(bool);
        });
        return returnArray;
    }
})

and in my controller:

$scope.sections = [false, false, false];
$scope.toggleSection = function(n) {
    $scope.sections[n] = $scope.sections[n] ? false : true;
}

However, I want the same toggleSection function to go to the position of the element that it shows, like...

$scope.toggleSection = function(n) {
    $scope.sections[n] = $scope.sections[n] ? false : true;
    window.scrollTo($("#" + n).position().top, 0);
}

But I can't do this because it takes time for the DOM to show the section that it's creating. Before that, the element (and its position) does not exist.

Setting a timeout would probably work, but that seems sloppy.

I suspect that I need to create some sort of callback or promise. Is that right?

解决方案

Custom directive, promise or anything else, if your action (scroll) relies on the DOM (and it does), you cannot avoid to execute it after an angular digest cycle.

Hence the short way to do that is indeed with a timeout:

$scope.toggleSection = function(n) {
  $scope.sections[n] = $scope.sections[n] ? false : true;
  $timeout(function() {
    window.scrollTo($("#" + n).position().top, 0);
  }, 0, false);
}

Note the third argument of $timeout being false: this is because you do not need to $apply the scope (run another digest cycle) after the timeout execute its callback since it is jQuery only.

Again, scrolling before the DOM is updated does not make sense for a browser, so you cannot avoid it (yet you can hide it).

这篇关于转到过滤后的 ng-repeat 元素的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆