Angularjs ng滚动条无法使用ng repeat

Angularjs ng滚动条无法使用ng repeat,angularjs,angularjs-ng-repeat,Angularjs,Angularjs Ng Repeat,在我的应用程序中,我想为div使用一个自定义滚动条。所以我使用了ng滚动条,它可以很好地处理静态数据。但是,每当我使用ng repeat获取数据时,它都不起作用。请在这方面帮助我。提前谢谢 myFile.html <style> .scrollme { max-height: 300px; } </style> <div ng-app="myapp"> <div class="container" ng-controller="m

在我的应用程序中,我想为div使用一个自定义滚动条。所以我使用了ng滚动条,它可以很好地处理静态数据。但是,每当我使用ng repeat获取数据时,它都不起作用。请在这方面帮助我。提前谢谢

myFile.html

<style>
  .scrollme {
    max-height: 300px;
   }
</style>

<div ng-app="myapp">
  <div class="container" ng-controller="myctrl">

    <button class="btn btn-info" ng-click="add();">add</button>
    <button class="btn btn-warning" ng-click="remove();">remove</button>

    <div class="well" >
      <div class="scrollme" ng-scrollbar bottom rebuild-on="rebuild:me">
        <h1>Scroll me down!</h1>
        <p ng-repeat="mi in me">{{mi.name}}</p>
      </div>
    </div>
  </div>
</div>

.我{
最大高度:300px;
}
添加
去除
把我滚下来!

{{mi.name}

myCtrl.js

var myapp = angular.module('myapp', ["ngScrollbar"]);
myapp.controller('myctrl', function ($scope) {
    $scope.me = [];
    for(var i=1;i<=20;i++){
        $scope.me.push({"name":i});
    }
    var a = $scope.me.length;
    $scope.add = function(){        
    $scope.me.push({"name":$scope.me.length+1});
    $scope.$broadcast('rebuild:me');
    }
    $scope.remove = function(){
        $scope.me.pop();
    }
});
var myapp=angular.module('myapp',[“ngScrollbar]”);
myapp.controller('myctrl',函数($scope){
$scope.me=[];

对于(var i=1;i尝试将
广播
调用添加到控制器的末尾,以便在控制器加载时触发。如果不起作用,请尝试添加:

$timeout(function () {
    $scope.$broadcast('rebuild:me');
}, 0);
// 0 optional, without it the time is assumed 0 which means next digest loop.
在控制器代码的末尾,而不是在add函数中。如果此方法有效,但前面的方法无效,则意味着ngRepeat没有及时完成动态内容的渲染,以便ngScrollbar正确更新

更新:通常,您可能需要将广播包装在add()中函数超时。我之所以这么说,是因为我怀疑发生了什么,是因为您向作用域变量添加了数据,然后在同一个函数调用中广播了所有数据。可能发生的情况是,在ngRepeat看到更新的作用域数据并添加其额外的DOM元素之前,广播事件被捕获,滚动条会重新计算。顺便说一句,如果您想在add()上重新计算滚动条,那么您也需要在remove()上重新计算滚动条

因此,您的add函数将变成:

$scope.add = function(){        
    $scope.me.push({"name":$scope.me.length+1});
    // wait until next digest loop to send event, this way ngRepeat has enough time to update(?)
    $timeout(function () {
        $scope.$broadcast('rebuild:me');
    });
}

请尝试ng scroll…另一个插件,但无需手动调整。 提及:


如果您使用jQuery,您可以试一试——它有更多可完全定制的CSS

带有ng repeat的示例如下:

JavaScript

var demoApp = angular.module('demoApp', ['jQueryScrollbar']);

demoApp.controller('SimpleController', function($scope){

    $scope.me = [];
    for(var i=1;i<=20;i++){
        $scope.me.push({"name":i});
    }

    $scope.add = function(){
        $scope.me.push({"name":$scope.me.length+1});
    }
    $scope.remove = function(){
        $scope.me.pop();
    }

    $scope.jqueryScrollbarOptions = {
        "onUpdate":function(container){
            setTimeout(function(){
                // scroll to bottom. timeout required as scrollbar restores
                // init scroll positions after calculations
                container.scrollTop(container.prop("scrollHeight"));
            }, 10);


        }
    };
});

这可能有点晚了

问题是,即使您已将内容添加到scope变量,angular仍没有完成向DOM添加p标记

console.log($('.well').find('p').length);
将内容推送到
$scope.me
后,您将了解发生了什么。(至少需要jQuery进行调试)

解决方案比你想象的要复杂得多

第1步:

ng控制器
添加到您的
ng repeat
(是的,这是允许的)

每当
ng repeat
操作DOM时,就会触发此控制器函数。我正在监视
$last
,它是
ng repeat
的范围变量。每当
ng repeat
加载DOM中的最后一个元素时,此函数将设置为true。当
$last
设置为
true
时,我将发出一个事件
loopload
。由于您使用循环将值推入
$scope.me
,因此每次推送都会触发此事件


步骤3:事件处理

在你的SimpleControl中(不再简单了,是吗?)

加载所有p元素后,发送到事件的
索引将等于
$scope.me.length-1
。因此您可以调用scroll rebuild。就是这样


这里是我使用的参考-

单击“添加”按钮后,滚动条是否工作?两件事:您可能希望将“重建:我”事件添加到scope.remove。由于您告诉滚动条在添加时进行更新,因此在有删除时也进行更新是有意义的。您可能还希望在控制结束时添加事件广播滚动,使其在初始渲染时激发,而无需单击add()。可能必须在$timeout(fund(){},0)内允许ngRepeat渲染idk。这也不起作用。我使用$scope.$broadcast('buildScrollbar');而不是$scope.$broadcast('rebuild:me');。我删除了对buildScrollbar()的调用ngScrollbar.js中的函数。它在开始时显示得非常完美,但当我单击“添加”按钮时,我的div高度正在下降。单击4到5次后,div高度完全消失。这太复杂了,但本质上是最好的解决方案。当您$watch($last)时,函数参数不是一个值,而是一个“isLast”值时,它将传递false,直到到达最后一个项时它为true。这意味着您可以在那里发出“rebuild:me”命令。无需回调主控制器并测试长度。
.scrollbar-dynamic {
    border: 1px solid #FCC;
    max-height: 300px;
    overflow: auto;
}
console.log($('.well').find('p').length);
<p ng-repeat="mi in me" ng-controller="loopController">{{mi.name}}</p>
demoApp.controller('loopController', function($scope) {
    $scope.$watch('$last', function(new_val) {
        new_val && $scope.$emit('loopLoaded', $scope.$index);
    });
});
$scope.$on('loopLoaded', function(evt, index) {
    if (index == $scope.me.length-1) {
        $scope.$broadcast('rebuild:me');
    }
});