在Angular模型更改后刷新Bootstrap ScrollSpy

时间:2013-01-11 18:18:24

标签: jquery-plugins twitter-bootstrap angularjs

我正在尝试使用bootstrap scollspy突出显示由角度转发器生成的列表项。

我遇到的问题是,在将角度模型更改应用到视图之前,我正在从角度控制器刷新scrollspy插件。

确保在更新DOM本身(不仅仅是角度模型)后发生scrollspy('refresh')调用的角度方法是什么?

模板:

<div class="span2" id="addressList">
    <ul class="nav nav-tabs nav-stacked affix">
       <li ng-repeat="addr in addresses"><a href="#{{addr.id}}">{{addr.id}}</a></li>
    </ul>
</div>

控制器:

$scope.httpSuccessCallback = function (data) 
     $scope.addresses.push(data);
     $('[data-spy="scroll"]').scrollspy('refresh'); //calls $('#addressList .nav > li > a')
 }

4 个答案:

答案 0 :(得分:5)

在不知道关于滚动间谍的任何的情况下,以下是您通常希望在Angular中使用JQuery插件的方式:

app.directive('scrollSpy', function (){
   return {
     restrict: 'A',
     link: function(scope, elem, attr) {
         elem.scrollSpy({ /* set up options here */ });

         //watch whatever expression was passed to the
         //scroll-spy attribute, and refresh scroll spy when it changes.
         scope.$watch(attr.scrollSpy, function(value) {
              elem.scrollSpy('refresh');
         });
     }
   };
});

然后在HTML中:

<div scroll-spy="foo">Do something with: {{foo}}</div>

以上示例非常通用,但它基本上将您的插件应用于元素,并在每次$ scope.foo更改时调用'refresh'或其他任何内容。

我希望有所帮助。

答案 1 :(得分:4)

我如何解决这个问题,使用Blesh的回答

模板:

  <body ng-app="address" ng-controller="AddressCtrl" scroll-spy="addresses">
    <div class="container">
      <form ng-submit="lookupAddress()">
        <input type="text" ng-model="addressText" />
        <button id="addressQueryBtn">Submit</button>
      </form>

      <div id="addressList">
        <ul>
          <li ng-repeat="addr in addresses">{{addr}}</li>
       </ul>
      </div>

    </div>
  </body>

Angular JS:

angular.module('address', []).
directive('scrollSpy', function($timeout){
  return function(scope, elem, attr) {
    scope.$watch(attr.scrollSpy, function(value) {
      $timeout(function() { elem.scrollspy('refresh') }, 200);
    }, true);
  }
});

function AddressCtrl($scope, $http) {
  $scope.addresses = [];

  $scope.lookupAddress = function() {
    $scope.addresses.push($scope.addressText);
    $scope.addressText = '';
  };
}

当观察范围var是对象或数组时,需要scope.watch(...)的第三个参数。不幸的是,这个解决方案仍然导致注释中随机提及的无法识别的表达式问题。我最终在监视功能中通过using a timeout解决了这个问题。

答案 2 :(得分:1)

在Angular中使用Scrollspy有一些挑战(可能为什么AngularUI在2013年8月仍然不包括Scrollspy)。

  1. 每次对DOM内容进行任何更改时,都必须刷新scrollspy。

      

    这可以通过$观察元素并为scrollspy('refresh')调用设置超时来完成。

  2. 如果您希望能够使用nav元素导航可滚动区域,则需要覆盖nav元素的默认行为。

  3.   

    这可以通过使用preventDefault来阻止导航和附加scrollTo函数来实现。

    我在Plunker上抛出了一个有效的例子:http://plnkr.co/edit/R0a4nJi3tBUBsluBJUo2?p=preview

答案 3 :(得分:-1)

我一直在寻找这个问题的解决方案一段时间,但我找不到一个。我最终通过创建带有一些指令的滚动间谍服务来实现我自己的。

该服务将跟踪所有间谍部分及其偏移量。这些指令将创建一个滚动事件,突出显示导航项并告诉服务所有部分所在的位置。由于此实现不会监视范围变量,因此应用程序需要广播消息以更新所有部分的偏移量。

您可以在Github上找到我的example