2013-12-20 29 views
1

我是AngularJS的新手。我使用的是AngularJS 1.2.5和Bootstrap 3.0。我正在尝试在我的应用中包含ScrollSpy。但是,我有一些挑战。我试图将代码找到here。目前,我的代码如下所示:在AngularJS中使用ScrollSpy

的index.html

<div class="row" scroll-spy> 
    <div class="col-md-3 sidebar"> 
    <ul style="position:fixed;" class="nav nav-pills nav-stacked"> 
     <li class="active" spy="overview"><a href="#overview">Overview</a></li> 
     <li spy="main"><a href="#main">Main Content</a></li> 
     <li spy="summary"><a href="#summary">Summary</a></li> 
     <li spy="links"><a href="#links">Other Links</a></li> 
    </ul> 
    </div> 

    <div class="col-md-9 content"> 
    <h3 id="overview">Overview</h3> 
    Lorem Ipsum Text goes here... 

    <h3 id="main">Main Body</h3> 
    Lorem Ipsum Text goes here... 

    <h3 id="summary">Summary</h3> 
    Lorem Ipsum text goes here... 

    <h3 id="links">Other Links</h3> 
    </div> 
</div> 

index.html.js

angular.module('td.controls.scrollSpy', []) 
    .directive('spy', function ($location) { 
    return { 
     restrict: 'A', 
     require: '^scrollSpy', 
     link: function (scope, elem, attrs, scrollSpy) { 
     var _ref; 
     if ((_ref = attrs.spyClass) == null) { 
      attrs.spyClass = 'current'; 
     } 
     elem.click(function() { 
      return scope.$apply(function() { 
      return $location.hash(attrs.spy); 
      }); 
     }); 
     return scrollSpy.addSpy({ 
      id: attrs.spy, 
      'in': function() { 
      return elem.addClass(attrs.spyClass); 
      }, 
      out: function() { 
      return elem.removeClass(attrs.spyClass); 
      } 
     }); 
     } 
    }; 
    }) 
    .directive('scrollSpy', function ($location) { 
    return { 
     restrict: 'A', 
     controller: function ($scope) { 
     $scope.spies = []; 
     return this.addSpy = function (spyObj) { 
      return $scope.spies.push(spyObj); 
     }; 
     }, 
     link: function (scope, elem, attrs) { 
     var spyElems; 
     spyElems = []; 
     scope.$watch('spies', function (spies) { 
      var spy, _i, _len, _results; 
      _results = []; 
      for (_i = 0, _len = spies.length; _i < _len; _i++) { 
      spy = spies[_i]; 
      if (spyElems[spy.id] == null) { 
       _results.push(spyElems[spy.id] = elem.find('#' + spy.id)); 
      } else { 
       _results.push(void 0); 
      } 
      } 
      return _results; 
     }); 
     return $($window).scroll(function() { 
      var highlightSpy, pos, spy, _i, _len, _ref; 
      highlightSpy = null; 
      _ref = scope.spies; 
      for (_i = 0, _len = _ref.length; _i < _len; _i++) { 
      spy = _ref[_i]; 
      spy.out(); 
      spyElems[spy.id] = spyElems[spy.id].length === 0 ? elem.find('#' + spy.id) : spyElems[spy.id]; 

      if (spyElems[spy.id].length !== 0) { 
       if ((pos = spyElems[spy.id].offset().top) - $window.scrollY <= 0) { 
       spy.pos = pos; 
       if (highlightSpy == null) { 
        highlightSpy = spy; 
       } 
       if (highlightSpy.pos < spy.pos) { 
        highlightSpy = spy; 
       } 
       } 
      } 
      } 
      return highlightSpy != null ? highlightSpy['in']() : void 0; 
     }); 
     } 
    }; 
    }) 
; 

当我在浏览器中,我得到几个错误运行此。当我最初运行它,我看到下面的错误在我的浏览器控制台:

TypeError: Object function (spyObj) { return $scope.spies.push(spyObj); } has no method 'addSpy' 
ReferenceError: $window is not defined 

我想不出一个)为什么我得到这些错误或b)如何得到这个简单的例子来工作。我非常喜欢这种在AngularJS中使用Scrollspy的方法。这是我见过的最干净的实现。出于这个原因,我很想弄清楚如何使这个工作。

回答

2

我最近碰到了亚历山大的解决方案,并且经历了翻译过程。

要回答您的直接问题:您需要将$window导入您的scrollSpy指令。

.directive('scrollSpy', function ($location, $window) { 

下面是完整的翻译我做了亚历山大的代码:

app.directive('scrollSpy', function ($window) { 
    return { 
    restrict: 'A', 
    controller: function ($scope) { 
     $scope.spies = []; 
     this.addSpy = function (spyObj) { 
     $scope.spies.push(spyObj); 
     }; 
    }, 
    link: function (scope, elem, attrs) { 
     var spyElems; 
     spyElems = []; 

     scope.$watch('spies', function (spies) { 
     var spy, _i, _len, _results; 
     _results = []; 

     for (_i = 0, _len = spies.length; _i < _len; _i++) { 
      spy = spies[_i]; 

      if (spyElems[spy.id] == null) { 
      _results.push(spyElems[spy.id] = elem.find('#' + spy.id)); 
      } 
     } 
     return _results; 
     }); 

     $($window).scroll(function() { 
     var highlightSpy, pos, spy, _i, _len, _ref; 
     highlightSpy = null; 
     _ref = scope.spies; 

     // cycle through `spy` elements to find which to highlight 
     for (_i = 0, _len = _ref.length; _i < _len; _i++) { 
      spy = _ref[_i]; 
      spy.out(); 

      // catch case where a `spy` does not have an associated `id` anchor 
      if (spyElems[spy.id].offset() === undefined) { 
      continue; 
      } 

      if ((pos = spyElems[spy.id].offset().top) - $window.scrollY <= 0) { 
      // the window has been scrolled past the top of a spy element 
      spy.pos = pos; 

      if (highlightSpy == null) { 
       highlightSpy = spy; 
      } 
      if (highlightSpy.pos < spy.pos) { 
       highlightSpy = spy; 
      } 
      } 
     } 

     // select the last `spy` if the scrollbar is at the bottom of the page 
     if ($(window).scrollTop() + $(window).height() >= $(document).height()) { 
      spy.pos = pos; 
      highlightSpy = spy; 
     }   

     return highlightSpy != null ? highlightSpy["in"]() : void 0; 
     }); 
    } 
    }; 
}); 


app.directive('spy', function ($location, $anchorScroll) { 
    return { 
    restrict: "A", 
    require: "^scrollSpy", 
    link: function(scope, elem, attrs, affix) { 
     elem.click(function() { 
     $location.hash(attrs.spy); 
     $anchorScroll(); 
     }); 

     affix.addSpy({ 
     id: attrs.spy, 
     in: function() { 
      elem.addClass('active'); 
     }, 
     out: function() { 
      elem.removeClass('active'); 
     } 
     }); 
    } 
    }; 
}); 

上面的代码还支持高亮显示菜单中的最后spy元素如果浏览器滚动至底部,其原代码没有。

0

如果你不会使它与工作NG-包括改变这种

if (spyElems[spy.id].offset() === undefined) { 
    // try to refind it 
    spyElems[spy.id] = elem.find('#' + spy.id); 
    if(spyElems[spy.id].offset() === undefined) 
     continue; 
} 
以下条件,

 if (spyElems[spy.id].offset() === undefined) { 
     continue; 
     }