13

我是 AngularJS 的新手,在我的应用程序中实现jQuery 自定义内容滚动器时遇到了一个问题。

当我使用 Angular 更新内容时,我需要更新滚动条,为此滚动条有一个update方法。我的问题是,我不知道在哪里调用它。内容的标记如下:

<div class="scroll-list nice-scrollbars">
    <ul class="gallery clearfix">
        <li class="extra-alt" ng-repeat="item in relatedItems.data">
            ...
        </li>
    </ul>
</div>

我试图在 Angular 的成功分支中调用更新方法$http.post

$scope.relatedItems = $http.post($scope.url, {
    'filterType': 'related', 'film': id
}).success(function() {
    $(".nice-scrollbars").mCustomScrollbar('update');
});

这不起作用,我认为是因为调用成功方法时,视图内容尚未更新(我可以使用alert函数看到它,关闭对话框后出现数据)

我能够使滚动条工作的唯一方法是使用滚动条的高级属性来观察内容的变化(这些是传递给滚动条的选项):

var scrollbarOpts = {
    scrollButtons:{
        enable:true
    },
    advanced:{
        updateOnContentResize: true
        //@TODO: get rid of this, correctly find where to call update method
    }
}

这是不好的做法,因为此选项会降低整个脚本的性能。 我想知道,调用 jQuery 方法根据需要更新 DOM 所需的正确位置在哪里,或者这种绑定如何在 AngularJS 中正确完成查看更改?

4

1 回答 1

14

DOM 操作应该在指令(而不是控制器)中完成。该指令应该 $watch() 你的模型进行更改,并且 watch 回调应该执行 jQuery DOM 操作。有时需要 $evalAsync 在 Angular 更新/修改 DOM 之后(但在浏览器渲染之前运行 jQuery 代码。$timeout如果您想在浏览器渲染之后执行某些操作,请使用)。看到这个答案,我提供了一个小提琴,展示了如何使用指令来 $watch() 模型属性,我在模拟 fetch() 函数中使用了 $evalAsync。

对于您的特定情况,我建议您首先在指令中尝试以下操作:

scope.$watch("relatedItems.data", function() {
   $(".nice-scrollbars").mCustomScrollbar('update');
});

如果这不起作用,试试这个:

scope.$watch("relatedItems.data", function() {
   scope.$evalAsync(  // you might need to wrap the next line in a function, not sure
      $(".nice-scrollbars").mCustomScrollbar('update')
   );
});
于 2012-12-22T17:36:37.177 回答