2013-09-23 1 views
4

나는 다음과 같은 엑스트라 AngularJS와 함께 내장 된 모바일 웹 앱 무한 스크롤을 내장 기능 :AngularJS에서 내 양방향 무한 스크롤에 문제가 있습니까?

  1. 내가 양방향 그것을 내장
  2. 그래서 그것을 밖으로 언로드 원이 모바일 웹 앱입니다 메모리 문제를 피하기 위해 내용을 보려는 경우

여기는 링크입니다.

는 지금, 나는 몇 가지 질문을하고 난 또한 작은 코드 검토 필요 :

  1. 내가 약속에 익숙하지 않다, 그러나 $digest 전에 실행할 then() 보인다. 따라서 코드를 $timeout으로 지연시켜야합니다. 나에게 그것은 뭔가 잘못되었다는 표시이다. 85 및 98 번 라인에서 $timeout을 제거하고 싶습니다. 85 번 라인의 $timeout은 비트 "hacky"이며, then() 이후에 실행해야합니다. 그렇지 않으면 작동하지 않으며 이유를 모르겠습니다. .
  2. 지시문에서 $scope 메서드를 호출하는 것이 "우수 사례"로 간주되는지 알고 싶습니다. 내 코드에서는 내 지시문에서 $scope.init(value)이라고합니다.
  3. position()에 jQuery를 포함시키는 것은 상당히 재미 있습니다. $.position()을 수행하는 기능을 가진 서비스를 사용해야합니까?

나는 그것들이 별도의 질문 일 수 있지만 실제로는 내 코드와 관련이 있다는 것을 알고 있습니다.

HTML :

<div id="fixed" scroll-watch="4" scroll-up="loadTop()" scroll-down="loadBottom()"> 
    <ul> 
     <li data-id="{{i.id}}" ng-repeat="i in items" ng-class="calculateType(i.id)">{{i.id}}</li> 
    </ul> 
</div> 

JS :

function Main($scope, $timeout, $q) { 
    var cleanup = 5; 

    $scope.items = []; 

    //This is called from the scrollWatch directive. IMO, this shouldn't be a good idea 
    $scope.init = function(value) { 
     var deferred = $q.defer(); 

     //This $timeout is used to simulate an Ajax call so I will keep it there 
     $timeout(function() { 
      $scope.items = [{id: +value}]; 

      $scope.loadTop(); 
      $scope.loadBottom(); 

      deferred.resolve(); 
     }, 200); 

     return deferred.promise; 
    }; 

    //This is only used to simulate different content's heights 
    $scope.calculateType = function(type) { 
     return 'type-' + Math.abs(type) % 4; 
    }; 

    $scope.loadBottom = function() { 
     var deferred = $q.defer(), 
      counter; 

     if ($scope.items.length > 1) { 
      $scope.items.splice(0, cleanup); 
     } 

     //This $timeout is used to simulate an Ajax call so I will keep it there 
     $timeout(function() { 
      counter = (($scope.items[$scope.items.length - 1]) || {id: 0}).id; 

      for (var i = 1; i < 6; i++) { 
       $scope.items.push({id: counter + i}); 
      } 

      deferred.resolve(); 
     }, 200); 

     return deferred.promise; 
    }; 

    $scope.loadTop = function() { 
     var deferred = $q.defer(), 
      counter; 

     //Why can't I use this here? 
     //$scope.items.splice($scope.items.length-cleanup, $scope.items.length); 

     //This $timeout is used to simulate an Ajax call so I will keep it there 
     $timeout(function() { 
      counter = (($scope.items[0]) || {id: 0}).id; 

      for (var i = 1; i < 6; i++) { 
       $scope.items.unshift({id: counter - i}); 
      } 

      deferred.resolve(); 
     }, 200); 

     return deferred.promise; 
    }; 

    //Why is this method needs to be delayed inside the directive? I would like to call it in loadTop() 
    $scope.removeBottom = function() { 
     $scope.items.splice($scope.items.length-cleanup, $scope.items.length); 
    }; 
} 

angular.module('scroll', []).directive('scrollWatch', ['$timeout', function($timeout) { 
    var lastScrollTop = 0; 

    return function($scope, elm, attr) { 
     var raw = elm[0]; 

     $scope.init(attr.scrollWatch).then(function() { 
      //Why do I need this? It looks like the resolve is called before the $digest cycle 
      $timeout(function() { 
       raw.scrollTop = $('li[data-id="' + attr.scrollWatch + '"]').position().top; 
      }, 300); //This value needs to be great enough so it is executed after the $scope.loadTop()'s resolve, for now, I know that I can set it to 300 but in real life app? 
     }); 

     elm.bind('scroll', function() { 
      if (raw.scrollTop > lastScrollTop && raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) { 
       $scope.$apply(attr.scrollDown); 
      } else if (raw.scrollTop < lastScrollTop && raw.scrollTop === 0) { 
       var scrollHeight = raw.scrollHeight; 

       $scope.$apply(attr.scrollUp).then(function() { 
        //Why do I need this? It looks like the resolve is called before the $digest cycle 
        $timeout(function() { 
         raw.scrollTop = raw.scrollHeight - scrollHeight; 

         //I would like to move this in the $scope.loadTop() 
         $scope.removeBottom(); 
        }); 
       }); 
      } 

      lastScrollTop = raw.scrollTop; 
     }); 
    }; 
}]); 

당신을 감사합니다 jsfiddle 링크를 클릭하고 싶지 않은 사람들을 위해

, 여기에 코드입니다

+0

약속을 해결하기 전에 $ scope. $ digest를 호출하십시오. http://jsfiddle.net/D5fT3/6/. 콜백 실행 후 $ timeout $ digest 호출합니다 생각합니다. – Sanjo

답변

1

http://www.youtube.com/watch?v=o84ryzNp36Q 약속에 대한 훌륭한 비디오, 어떻게 작성하고 어떻게 작동하는지 알아보십시오.

https://github.com/stackfull/angular-virtual-scroll 화면에 아무 것도로드하지 않는 ng-repeat에 대한 지시어 대체는 내가 무엇을 찾고 있는지 정확히 알 수 있습니다.

나는 이것을 주석으로 달았지만, 50 cred 또는 평판 또는 그들이 무엇이라고 부르는 것이 필요합니다.

관련 문제