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

Teo*_*.sk 13 javascript jquery scrollbar angularjs

我是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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

var scrollbarOpts = {
    scrollButtons:{
        enable:true
    },
    advanced:{
        updateOnContentResize: true
        //@TODO: get rid of this, correctly find where to call update method
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*cok 14

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

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

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

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

scope.$watch("relatedItems.data", function() {
   scope.$evalAsync(  // you might need to wrap the next line in a function, not sure
      $(".nice-scrollbars").mCustomScrollbar('update')
   );
});
Run Code Online (Sandbox Code Playgroud)