如何在视图更改时从AngularJS调用JQuery函数

时间:2012-12-22 12:32:45

标签: javascript jquery scrollbar angularjs

我是AngularJS的新手,在我的应用程序中实现jQuery custom content scroller时,我处理了一个问题。

我需要更新滚动条,当我使用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
    }
}

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

1 个答案:

答案 0 :(得分:14)

DOM操作应该在指令(而不是控制器)中完成。该指令应该$ watch()你的模型进行更改,并且watch回调应该执行jQuery DOM操作。在Angular更新/修改DOM之后(但在浏览器渲染之前),有时需要$ evalAsync来运行jQuery代码。如果你想在浏览器渲染后执行某些操作,请使用$timeout。请参阅this answer,其中我提供了一个小提示,展示如何使用$ watch()模型属性的指令,并在mock 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')
   );
});