2013-05-31 24 views
47

Tôi có một danh sách giống như thế này:.

<li ng-repeat="document in DisplayDocuments()" ng-class="IsFiltered(document.Filtered)"> 
    <span><input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /></span> 
    <span>{{document.Name}}</span> 
</li> 

tôi ràng buộc danh sách này trong bộ điều khiển của tôi, như thế này:

$scope.Documents = $http.get('/Documents/DocumentsList/' + caseId).then(function(result) { 
    return result.data; 
}); 

Khi điều này chạy, tôi không nhận được bất kỳ kết quả nào. khi tôi xóa phương thức then, tôi nhận được ba dòng trống, làm cho số đếm OK, nhưng không có thông tin nào được hiển thị.

Tôi biết "everthing" khác hoạt động, vì trước đây tôi đã điền danh sách với jQuery, tôi đang làm gì sai?

Đây là phản hồi từ máy chủ:

{Id:3f597acf-a026-45c5-8508-bc2383bc8c12, Name:ZZ_BL0164_Skisse BL0164_945111.pdf, Order:1,…} 
{Id:46f51f1f-02eb-449a-9824-8633e8ae7f31, Name:ZB_BL0201_Firmaattest BL0201_945111.pdf, Order:1,…} 
{Id:fddd1979-c917-4b32-9b83-b315f66984ed, Name:ZA_BL0228_Legitimasjonsskjema BL0228_945111.pdf,…} 
+0

Tôi thường sử dụng .get (...). Thành công (hàm (dữ liệu) {}); có lẽ bạn có thể thêm console.log (kết quả) và xem những gì nó kết quả đầu ra? Tôi cũng đảm bảo rằng url bạn gọi cũng được tạo thành. caseId là gì? –

+1

Tôi cũng đã thử điều đó, chỉ nghĩ rằng nó trông đẹp hơn, và dễ theo dõi hơn, đó là lý do tại sao tôi muốn cho nó đi. Tôi đã thấy mọi người sử dụng cả hai, nhưng không thể có được cách này để làm việc. – ruffen

+0

Bạn đang ràng buộc 'Tài liệu' với phạm vi của bạn, nhưng bằng cách sử dụng' DisplayDocuments() 'trong' ng-repeat' trong đó 'DisplayDocuments()' bắt nguồn từ đâu? –

Trả lời

52

Phương thức $ http trả lại lời hứa, không thể được lặp, vì vậy bạn phải đính kèm các kết quả vào biến phạm vi thông qua callbacks:

$scope.documents = []; 
$http.get('/Documents/DocumentsList/' + caseId) 
    .then(function(result) { 
    $scope.documents = result.data; 
}); 

Bây giờ, vì đây xác định các biến documents chỉ sau khi kết quả được tìm nạp, bạn cần phải khởi tạo biến documents trên phạm vi trước: $scope.documents = []. Nếu không, ng-lặp lại của bạn sẽ bị nghẹt thở. Bằng cách này, ng-lặp lại đầu tiên sẽ trả về một danh sách trống, bởi vì documents mảng trống vào lúc đầu, nhưng ngay khi nhận được kết quả, ng-lặp lại sẽ chạy lại vì `tài liệu` đã thay đổi trong thành công gọi lại.

Ngoài ra, bạn có thể muốn thay đổi bạn biểu ng-repeat đến:

<li ng-repeat="document in documents" ng-class="IsFiltered(document.Filtered)"> 

vì nếu chức năng DisplayDocuments() bạn đang thực hiện cuộc gọi đến máy chủ, hơn cuộc gọi này sẽ được thực hiện nhiều lần, do các chu kỳ $ digest.

+0

Vì vậy, tôi chỉ có thể trả lời lời hứa về phạm vi khi tôi không trả lại mảng? Displaydocuments không thực hiện cuộc gọi đến máy chủ, cảm ơn cho người đứng đầu lên anyway. – ruffen

+1

Ý tôi là, nếu bạn viết '$ scope.documents = $ http.get (...)' hơn 'tài liệu' sẽ tham chiếu một lời hứa (từ dịch vụ $ q), bởi vì đó là những gì dịch vụ $ http trả về, lời hứa . – Stewie

+2

Vâng, hiểu điều đó, nhưng tôi nghĩ góc cạnh có thể giải quyết lời hứa đó một cách tự động? Rõ ràng tôi sai rồi. – ruffen

1

Hãy thử sử dụng success() gọi lại

$http.get('/Documents/DocumentsList/' + caseId).success(function (result) { 
    $scope.Documents = result; 
}); 

Nhưng bây giờ kể từ Documents là một mảng và không phải là một lời hứa, hãy tháo ()

<li ng-repeat="document in Documents" ng-class="IsFiltered(document.Filtered)"> <span> 
      <input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /> 
     </span> 
<span>{{document.Name}}</span> 

</li> 
6

Thực ra bạn nhận được promise trên $http.get.

Cố gắng sử dụng dòng người sau:

<li ng-repeat="document in documents" ng-class="IsFiltered(document.Filtered)"> 
    <span><input type="checkbox" name="docChecked" id="doc_{{document.Id}}" ng-model="document.Filtered" /></span> 
    <span>{{document.Name}}</span> 
</li> 

đâu documents là mảng của bạn.

$scope.documents = []; 

$http.get('/Documents/DocumentsList/' + caseId).then(function(result) { 
    result.data.forEach(function(val, i) { 
     $scope.documents.push(/* put data here*/); 
    }); 
}, function(error) { 
    alert(error.message); 
});      
25

Không thể ràng buộc trực tiếp lời hứa từ $http (Tôi không biết chính xác lý do). Tôi đang sử dụng dịch vụ gói mà hoạt động hoàn hảo cho tôi:

.factory('DocumentsList', function($http, $q){ 
    var d = $q.defer(); 
    $http.get('/DocumentsList').success(function(data){ 
     d.resolve(data); 
    }); 
    return d.promise; 
}); 

và liên kết với nó trong bộ điều khiển:

function Ctrl($scope, DocumentsList) { 
    $scope.Documents = DocumentsList; 
    ... 
} 

CẬP NHẬT !:

Trong góc 1.2 hứa hẹn tự động Unwrap đã xóa bỏ. Xem http://docs.angularjs.org/guide/migration#templates-no-longer-automatically-unwrap-promises

+0

Tôi vẫn không hoàn toàn chắc chắn như thế nào, nhưng người đàn ông, bạn đã kết thúc đau khổ của tôi. Cảm ơn bạn! – Davion

+0

@Davion và bất kỳ ai khác tự hỏi điều gì đang xảy ra trong mã này, $ http trả về một lời hứa http kết thúc tốt đẹp đối tượng phản hồi, chứ không phải dữ liệu thực tế. Đó là lý do tại sao bạn không thể "liên kết" trực tiếp với nó. Ở đây, dịch vụ $ q đang được sử dụng để tạo ra một lời hứa mới đang được giải quyết cho dữ liệu thực tế. Làm việc với lời hứa đó, bộ điều khiển có thể nhận được dữ liệu thực tế thay vì chỉ phản hồi http. Các phương thức BTW, $ http _success_ và _error_ không được chấp nhận, do đó, việc sử dụng _then_ hiện được khuyến nghị. – BitMask777

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