web-dev-qa-db-fra.com

Angularjs $ http.get (). Then et liaison à une liste

J'ai une liste qui ressemble à ceci:

<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>

Je lie cette liste dans mon contrôleur, à ceci:

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

Quand cela fonctionne, je n'obtiens aucun résultat. Lorsque je supprime la méthode then, je reçois trois lignes vides, ce qui rend le décompte OK, mais aucune information n'est affichée.

Je sais que "tout le reste" fonctionne, puisque j'ai déjà rempli la liste avec jQuery, que fais-je de travers?

Voici la réponse du serveur:

{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,…}
50
ruffen

Les méthodes $ http renvoient une promesse, qui ne peut pas être itérée. Vous devez donc attacher les résultats à la variable scope via les rappels:

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

Maintenant, puisque ceci définit la variable documents seulement après que les résultats ont été récupérés, vous devez initialiser la variable documents au préalable: $scope.documents = []. Sinon, votre ng-repeat va s'étouffer.

De cette façon, ng-repeat retournera d’abord une liste vide, parce que documents tableau est d’abord vide, mais dès que les résultats sont reçus, ng-repeat sera exécuté à nouveau car les `documents`` ont été modifiés dans le dossier. rappel de succès.

Aussi, vous voudrez peut-être modifier votre expression ng-repeat en:

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

parce que si votre fonction DisplayDocuments() appelle le serveur, cet appel sera exécuté à plusieurs reprises, en raison des cycles $ digest.

54
Stewie

La promesse est revenue de $http ne peut pas être lié directement (je ne sais pas exactement pourquoi). J'utilise un service d'emballage qui fonctionne parfaitement pour moi:

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

et se lier au contrôleur:

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

UPDATE!:

Dans Angular angulaires 1.2 promesses de décompression automatique ont été supprimées. Voir http://docs.angularjs.org/guide/migration#templates-no-longer-automatiquement-unwrap-promises)

26
vitalets

En fait, vous obtenez promise sur $http.get.

Essayez d'utiliser le flux suivi:

<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>

documents est votre tableau.

$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);
});                       
6
Maxim Shoustin

Essayez d’utiliser le rappel success()

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

Mais maintenant, puisque Documents est un tableau et non une promesse, supprimez le ()

<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>
1
Mark Coleman