我尝试从解决方案到这个工作

How to retain scroll position of ng-repeat in AngularJS?

在删除ng-repeat中的顶部项目时保持滚动位置,但无法找出执行此操作的代码.

另外,请注意,列表应按照与项目数组相同的顺序打印,而不是像示例那样反向打印.

解决方案的代码:

angular.module("Demo",[])

.controller("DemoCtrl",function($scope) {
  $scope.items = [];

  for (var i = 0; i < 10; i++) {
    $scope.items[i] = {
      id: i,name: 'item ' + i
    };
  }

  $scope.addNewItem = function() {
    $scope.items = $scope.items.concat({
      id: $scope.items.length,name: "item " + $scope.items.length
    });
  };
})

.directive("keepScroll",function(){

  return {

    controller : function($scope){
      var element = 0;

      this.setElement = function(el){
        element = el;
      }

      this.addItem = function(item){
        console.log("Adding item",item,item.clientHeight);
        element.scrollTop = (element.scrollTop+item.clientHeight+1); //1px for margin
      };

    },link : function(scope,el,attr,ctrl) {

     ctrl.setElement(el[0]);

    }

  };

})

.directive("scrollItem",function(){


  return{
    require : "^keepScroll",att,scrCtrl){
      scrCtrl.addItem(el[0]);
    }
  }
})

我尝试做的是改变

element.scrollTop = (element.scrollTop + item.clientHeight+1)

element.scrollTop = (element.scrollTop - item.clientHeight+1)

并按’id’而不是’-id’按顺序打印

我认为最初的解决方案有点像hacky ……但这是一个以它为基础的工作编辑.

问题是解决方案取决于添加到ng-repeat的项目.如果查看scrollItem指令,它只会导致keepScroll指令在链接器执行时重新调整scrollTop.这仅在项目添加而不是删除时发生.

而编辑则侦听范围.$on(‘$destroy’)事件.但是,此时的问题是该元素不再具有clientHeight,因为它已从DOM中删除.因此解决方案是在创建时保存其高度,然后告诉keepScroll删除元素的高度是多少.

注意:如果滚动条一直到底部,这似乎会导致滚动跳转,因此您需要将该情况视为异常.

工作JSBin:http://jsbin.com/geyapugezu/1/edit?html,output

以供参考:

HTML

<!DOCTYPE html>
<html>
<head>
<script src="//code.angularjs.org/1.3.0-beta.7/angular.js"></script>
  <Meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body ng-app="Demo" ng-controller="DemoCtrl">
  <div class="wrapper" keep-scroll>
    <div class="item" scroll-item ng-repeat="item in items | orderBy: 'id'">
      {{ item.name }}
    </div>
  </div>
  <button ng-click="removeItem()">
    Remove item
  </button>
</body>
</html>

CSS

.wrapper {
  width: 200px;
  height: 300px;
  border: 1px solid black;
  overflow: auto;
}
.item {
  background-color: #ccc;
  height: 100px;
  margin-bottom: 1px;
}

JS

angular.module("Demo",[])
  .controller("DemoCtrl",function($scope) {
    $scope.items = [];

    for (var i = 0; i < 10; i++) {
      $scope.items[i] = {
        id: i,name: 'item ' + i
      };
    }

    $scope.removeItem = function() {
      $scope.items = $scope.items.slice(1);
    };
})
.directive("keepScroll",function(){

  return {
    controller : function($scope){
      var element = 0;

      this.setElement = function(el){
        element = el;
      };

      this.itemRemoved = function(height){
        element.scrollTop = (element.scrollTop - height - 1); //1px for margin
        console.log("Item removed",element.scrollTop);
      };

    },ctrl) {
     ctrl.setElement(el[0]);

    }

  };

})
.directive("scrollItem",function(){


  return {
    require : "^keepScroll",scrCtrl){
      var height = el[0].clientHeight;

      scope.$on('$destroy',function() {
        scrCtrl.itemRemoved(height);
      });
    }
  };
});

编辑

或者,这样做.不需要scrollItem,而是我们观察ng-repeat项目的更改并相应地重新调整scrollTop.

JSBin:http://jsbin.com/dibeqivubi/edit?html,output

JS

angular.module("Demo",['$scope',name: 'item ' + i
      };
    }

    $scope.removeItem = function() {
      $scope.items = $scope.items.slice(1);
    };
}])
.directive("keepScroll",function() {
  return {
    link : function(scope,ctrl) {
      var scrollHeight;

      scope.$watchCollection('items',function(n,o) {
        // Instantiate scrollHeight when the list is
        // done loading.
        scrollHeight = scrollHeight || el[0].scrollHeight;
        // Adjust scrollTop if scrollHeight has changed (items
        // have been removed)
        el[0].scrollTop = el[0].scrollTop - (scrollHeight - el[0].scrollHeight);
        // Remember current scrollHeight for next change.
        scrollHeight = el[0].scrollHeight;
      });
    }

  };
});

HTML

<!DOCTYPE html>
<html>
<head>
<script src="//code.angularjs.org/1.3.0-beta.7/angular.js"></script>
  <Meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body ng-app="Demo" ng-controller="DemoCtrl">
  <div class="wrapper" keep-scroll>
    <div class="item" ng-repeat="item in items | orderBy: 'id'">
      {{ item.name }}
    </div>
  </div>
  <button ng-click="removeItem()">
    Remove item
  </button>
</body>
</html>

从顶部删除项目时,如何在AngularJS中保留ng-repeat的滚动位置的更多相关文章

  1. Html5 滚动穿透的方法

    这篇文章主要介绍了Html5 滚动穿透的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. 使用layui实现左侧菜单栏及动态操作tab项的方法

    这篇文章主要介绍了使用layui实现左侧菜单栏及动态操作tab项的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解三种方式实现平滑滚动页面到顶部的功能

    这篇文章主要介绍了详解三种方式实现平滑滚动页面到顶部的功能的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. 移动端html5判断是否滚动到底部并且下拉加载

    这篇文章主要介绍了移动端html5判断是否滚动到底部并且下拉加载,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. 在iOS上绘制扭曲的文本

    使用iOS9及更高版本中提供的标准API,如何在绘制文本时实现扭曲效果?

  6. ios – 如果Element符合给定的协议,则扩展阵列以符合协议

    如果是这样,语法是什么?解决方法Swift4.2在Swift4.2中,我能够使用符合这样的协议的元素扩展数组:

  7. ios – 如何在swift中获取2数组的常见元素列表

    (双关语)编辑:,你可以这样做这个实现是丑陋的.

  8. Swift 函数Count,Filter,Map,Reduce

    Count-统计数量文档示例Filter-条件过滤文档示例-过滤长度大于4的字符串也可以简化Map-映射集合类型,返回数组文档示例同样可以简化Reduce-把数组结合到一起文档示例可以简化进一步简化

  9. Swift语法——Swift Sequences 探究

    今天看到Array的API中有这么一个声明的函数:函数名为extend,所需参数是S类型的newElements,而S首先要实现SequenceType协议。看看APTGeneratorType必须要实现一个函数next(),它的作用就是返回一个Element,注释里说的很清楚:它的作用就是一直返回元素,直到最后。1)Swift调用generate()来生成了一个Generator,这个对象是一个私有的变量即__g;2)__g调用了next()函数,返回了一个optional类型对象element?。这个

  10. Swift 中数组和链表的性能

    尽管如此,我觉得链表的例子非常有意思,而且值得实现和把玩,它有可能会提升数组reduce方法的性能。同时我认为Swift的一些额外特性很有趣:比如它的枚举可以灵活的在对象和具体方法中自由选择,以及“默认安全”。这本书未来的版本可能就会用Swift作为实现语言。拷贝数组消耗的时间是线性的。使用链表还有其他的代价——统计链表节点的个数所需要的时间是统计数组元素个数时间的两倍,因为遍历链表时的间接寻址方式是需要消耗时间的。

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部