2015-11-17 25 views
6

Tôi đang sử dụng md-virtual-repeat chỉ thị Angular Material để cuộn vô hạn và tôi cần thay thế chức năng thời gian chờ là demo $ với yêu cầu $ http. Nhưng tôi không thể giải quyết đúng. Trong mã bên dưới, cuộn vô hạn hoạt động tốt nhưng không hiển thị dữ liệu từ yêu cầu http. Vấn đề là tôi không biết cách kết nối $ http với infiniteItems.

Here là bộ tách.

index.html

<body ng-app="infiniteScrolling" class="virtualRepeatdemoInfiniteScroll"> 
<div ng-controller="AppCtrl as ctrl" ng-cloak> 
    <md-content layout="column"> 
     <md-virtual-repeat-container id="vertical-container" flex> 
      <div md-virtual-repeat="item in ctrl.infiniteItems" md-on-demand 
       class="repeated-item" flex> 
       {{item.id}} 
      </div> 
     </md-virtual-repeat-container> 
    </md-content> 
</div> 
</body> 

JS:

(function() { 
'use strict'; 
angular 
    .module('infiniteScrolling', ['ngMaterial']) 
    .controller('AppCtrl', function ($timeout,$scope,$http) { 
    this.infiniteItems = { 
      numLoaded_: 0, 
      toLoad_: 0, 
      items:[], 
      getItemAtIndex: function (index) { 
       if (index > this.numLoaded_) { 
        this.fetchMoreItems_(index); 
        return null; 
       } 
       return index; 
      }, 
      getLength: function() { 
       return this.numLoaded_ + 5; 
      }, 
      fetchMoreItems_: function (index) { 
       if (this.toLoad_ < index) { 
        this.toLoad_ += 20; 

        $http.get('items.json').success(function (data) { 
         var items = data; 
         for (var i = 0; i < items.length; i++) { 
          this.items.push(items[i].data); 
         } 
         this.numLoaded_ = this.toLoad_; 
        }.bind(this)); 
       } 
      } 
     }; 
    }); 
})(); 

Trả lời

11

Cái này hoạt động:

plnkr

  • getItemAtIndex trả lại chỉ số và không phải là mục
  • nếu bạn kiểm tra những gì bạn đẩy, bạn sẽ thấy rằng tại dòng 33 trong plunkr tôi concat obj.data, không đơn giản obj
(function() { 
    'use strict'; 
    angular.module('infiniteScrolling', ['ngMaterial']) 
     .controller('AppCtrl', function ($scope, $http) { 
      // In this example, we set up our model using a plain object. 
      // Using a class works too. All that matters is that we implement 
      // getItemAtIndex and getLength. 
      var vm = this; 
      vm.infiniteItems = { 
       numLoaded_: 0, 
       toLoad_: 0, 
       items: [], 

       // Required. 
       getItemAtIndex: function (index) { 
        if (index > this.numLoaded_) { 
         this.fetchMoreItems_(index); 
         return null; 
        } 
        return this.items[index]; 
       }, 

       // Required. 
       getLength: function() { 
        return this.numLoaded_ + 5; 
       }, 

       fetchMoreItems_: function (index) { 
        if (this.toLoad_ < index) { 
         this.toLoad_ += 5; 
         $http.get('items.json').then(angular.bind(this, function (obj) { 
          this.items = this.items.concat(obj.data); 
          this.numLoaded_ = this.toLoad_; 
         })); 
        } 
       } 
      } 
     }) 
})(); 
+0

Cảm ơn bạn, Nó hoạt động. Nhưng tôi không biết tại sao cho toLoad _ + = 20, khi tôi đi xuống cuộn các dữ liệu tải với một sự chậm trễ lớn, rất xuống không bao giờ tải không giống nhau cho toLoad _ + = 10. –

+0

Vâng, thực sự nó tạo ra phần tử trong DOM nhưng vì api của bạn trả về 5 phần tử, iirc, nó không có đủ dữ liệu để khởi tạo, vì vậy chúng trống/trống. –

+1

Cảm ơn, bạn đã đúng. Tôi chỉ muốn thêm một điểm nữa: Tôi nghĩ rằng thay thế 'dữ liệu' bằng' obj.data' không phải là một phần của giải pháp khi tôi đang sử dụng 'success' thay vì' then' và nó trả về dữ liệu không kết quả, nhưng sử dụng 'concat 'là một phần của giải pháp. Bởi vì khi tôi xóa mã không hoạt động chính xác. Nó có một nhược điểm khi nó lưu trữ tất cả dữ liệu (tất cả các dữ liệu ngoài xem) trong bộ nhớ không chỉ dữ liệu trong xem. –

0

On mỗi cuộc gọi api cố gắng để có được thời tiết db có ít hồ sơ hơn hay không. và thêm điều kiện đó vào hàm fetchMoreItems_.

fetchMoreItems_: function (index) { 
       if (this.toLoad_ < index && hasMoreRecords) { 
        this.toLoad_ += 5; 

Trong mã của chúng tôi chúng tôi nhận được thông tin chi tiết như

  • sCurrentPage: 3
  • sMore: true == >> điều này chỉ ra rằng db có nhiều hồ sơ hay không sau khi trang quyến rũ dữ liệu khôn ngoan .
  • sTotalPages: 4
  • sTotalRecords: 36
+0

Và câu nói của bạn nó tạo ra phần tử trong DOM và nếu chúng ta nhận được các bản ghi nhỏ hơn cho thấy các bản ghi trống. Vì vậy, làm thế nào tôi có thể loại bỏ hoặc ngừng tạo ra những hồ sơ trống. Bạn có thể vui lòng giúp đỡ ... –

0

đến đây và nhìn thấy @ câu trả lời alessandro-buggin mà was very helpful. Tôi đã phải thay đổi nó một chút, vì vậy tôi nghĩ đến việc chia sẻ nó để những người khác giúp đỡ. Tôi cần thiết:

  • để tránh bị yêu cầu cuộn khi đã phục hồi dữ liệu (sử dụng this.hold)
  • yêu cầu dừng lại khi toàn bộ dữ liệu đã được nhận được từ backend (sử dụng this.stop_)
  • ẩn nội dung trong khi xếp hàng, để tránh các trục trặc hoặc các phần tử rỗng (một lần nữa sử dụng this.hold). Theo quan điểm, bạn cần sử dụng ng-hide trên phần tử đó vì ng-if tránh phần tử tồn tại để nó không tải lần đầu tiên.
  • triển khai phương thức làm mới để tải lại dữ liệu khi thông số/bộ lọc thay đổi từ biểu mẫu bên ngoài.

Xa hoàn hảo nhưng hoạt động khá tốt.

vm.elements = null; 
vm.infiniteItems = { // Start of infinte logic 

stop_: false, 
hold: false, 
numLoaded_: 0, 
toLoad_: 0, 
items: [], 

refresh: function() { 
    this.stop_ = false; 
    this.hold = false; 
    this.numLoaded_ = 0; 
    this.toLoad_ = 0; 
    this.items = []; 
}, 

getItemAtIndex: function (index) { 
    if (!this.hold) { 
     if (index > this.numLoaded_) { 
      this.fetchMoreItems_(index); 
      return null; 
     } 
    } 
    return this.items[index]; 
}, 

getLength: function() { 
    if (this.stop_) { 
     return this.items.length; 
    } 
    return this.numLoaded_ + 5; 
}, 

fetchMoreItems_: function (index) { 
    if (this.toLoad_ < index) { 

     this.hold = true; 
     this.toLoad_ += 5; 

     var start = this.numLoaded_; 
     if (start > 0) start++; 

     MyService.getData(parameters) 
     .then(angular.bind(this, function (obj) { 

      if (obj && obj.elements > 0) { 
      vm.elements = obj.elements; 
      this.items = this.items.concat(obj.data); 

      if (obj.elements < this.toLoad_) { 
       this.stop_ = true; 
      } 
      this.numLoaded_ = this.items.length; 
      this.hold = false; 

      } else { // if no data 
      vm.elements = 0; 
      } 
     })); 
    } 
} 

} // End of infinte logic 

Lưu ý: dịch vụ của tôi trả về một đối tượng sáng tác như thế này: obj = {elements: INTEGER, data: ARRAY} nơi yếu tố cho bạn biết chiều dài của các truy vấn đầy đủ.

Các vấn đề liên quan