2013-04-23 24 views
21

Làm cách nào để AngularJS hiển thị bộ nạp cho đến khi dữ liệu tải xong?AngularJS: hiển thị tải HTML cho đến khi dữ liệu được tải

Nếu bộ điều khiển của tôi có $scope.items = [{name: "One"}] thiết lập tĩnh và trình tải AJAX có mã số $scope.items[0]['lateLoader'] = "Hello", tôi muốn trình quay hiển thị cho đến khi tải AJAX hoàn tất, sau đó điền khoảng kết nối với dữ liệu đã truy xuất.

<ul ng-repeat="item in items"> 
    <li> 
    <p>Always present: {{item.name}}</p> 
    <p>Loads later: <span ng-bind="item.lateLoader"><i class="icon icon-refresh icon-spin"></i></span></p> 
    </li> 
</ul> 

Mã này sẽ điền vào khoảng giới hạn ngay lập tức và khi item.lateLoader để trống thì hộp xoay được thay thế bằng không có gì.

Tôi nên làm như thế nào?

+0

tại sao không đặt hình ảnh bộ tải tĩnh trong đánh dấu? – vittore

Trả lời

23

tôi sẽ tạo ra một chỉ thị tùy theo câu trả lời khác, nhưng đây là cách bạn có thể làm nó không có chỉ thị có thể là một ý tưởng hay để tìm hiểu trước khi tham gia vào các chức năng phức tạp hơn .. Một vài điều cần lưu ý:

  1. Sử dụng một setTimeout để mô phỏng cuộc gọi ajax
  2. Biểu tượng tải được tải sẵn và bị ẩn khi dữ liệu tải. Chỉ là một chỉ thị ng-hide đơn giản.
  3. Không có hình ảnh tải trong ví dụ của tôi chỉ là một số văn bản bị ẩn (rõ ràng là html của bạn sẽ có tham chiếu css chính xác).

Demo: http://plnkr.co/edit/4XZJqnIpie0ucMNN6egy?p=preview

Xem:

<ul > 
    <li ng-repeat="item in items"> 
    <p>Always present: {{item.name}}</p> 
    <p>Loads later: {{item.lateLoader}} <i ng-hide="item.lateLoader" class="icon icon-refresh icon-spin">loading image i don't have</i></p> 
    </li> 
</ul> 

Bộ điều khiển:

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    $scope.items = [{name: "One"}]; 
    setTimeout(function() { 
    $scope.$apply(function() { 
    $scope.items[0].lateLoader = 'i just loaded'; 
    }); 
    }, 1000); 
}); 
5

Tôi sẽ tạo chỉ thị tùy chỉnh và đặt đánh dấu mặc định bằng spinner.

Dưới đây là một số liên kết trên chỉ thị tùy chỉnh

1) video đầu vỏ trứng là tuyệt vời! http://www.egghead.io/video/xoIHkM4KpHM

2) docs góc chính thức trên thị http://docs.angularjs.org/guide/directive

3) Tốt tổng quan về góc trong 60ish phút http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx

+1

Tôi đồng ý với điều này mặc dù ông cũng có thể chỉ làm một 'ng-show' hoặc' ng-hide' dựa trên dữ liệu là có hay không (một số điều kiện) – lucuma

+0

@lucuma Yeah, nhưng nó có vẻ là điều tái sử dụng tốt để sống trong đó là chỉ thị riêng. – vittore

+0

Tôi khá mới với Angular - nếu bạn là một ví dụ hoặc một liên kết đến tài liệu mà thực sự hữu ích, mặc dù tôi rất vui khi tự mình đi săn tài liệu! –

0

@lucuma,

Great câu trả lời, một sự thay thế có thể phải tiêm $ timeout và thay thế functio thời gian chờ gốc n:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope, $timeout) { 

     $scope.name = 'World'; 
     $scope.items = [{name: "One"}]; 
     $timeout(function() { 
       $scope.$apply(function() { 
         $scope.items[0].lateLoader = 'i just loaded'; 
       }); 
     }, 1000); 
}); 
+0

Các setTimeout đã được chỉ được sử dụng để mô phỏng một chờ đợi mặc dù bạn là đúng nó sẽ có được tốt hơn để sử dụng $ timeout. – lucuma

+4

Thời gian chờ $ là hữu ích vì nó kết thúc cuộc gọi lại vào $ tự động áp dụng. I E. bạn có thể loại bỏ '$ scope. $ apply (function() {' từ ví dụ của bạn –

19

Tôi thực sự đã sử dụng giải pháp này trong một thời gian bây giờ hoạt động tốt và tốt hơn là sử dụng hết thời gian chờ theo ý kiến ​​của tôi. Tôi đang sử dụng tài nguyên $, nhưng bạn có thể làm điều tương tự với $ http. Trên các đối tượng $ resource của tôi, tôi thêm bit vào đoạn mã sau được đặt thành true.

$scope.customer = $resource(dataUrl + "/Course/Social/" + courseName) 
    .get({}, function (data) { data.loaded = true; }); 

Sau đó, theo quan điểm của tôi, tôi có thể sử dụng:

ng-hide="customer.loaded" 

Tất nhiên, tôi sẽ không sử dụng một nguồn tài nguyên $ trực tiếp trong một bộ điều khiển, tôi trích rằng đến một dịch vụ customerRepository, nhưng nó đã được đơn giản hơn để hiển thị nó theo cách này.

+1

Đây là giải pháp tốt nhất. – Steven

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