Angularjs $http.get(), а затем привязка к списку - программирование
Подтвердить что ты не робот

Angularjs $http.get(), а затем привязка к списку

У меня есть список, который выглядит так:

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

Я привязываю этот список в своем контроллере, чтобы:

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

Когда это выполняется, я не получаю никаких результатов. когда я удаляю метод then, я получаю три пустые строки, делая число ОК, но информация не отображается.

Я знаю, что "everthing" else работает, поскольку я ранее заполнял список с помощью jQuery, что я делаю неправильно?

Здесь ответ от сервера:

{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,…}
4b9b3361

Ответ 1

$http-методы возвращают обещание, которое нельзя повторить, поэтому вам нужно прикрепить результаты к переменной области видимости через обратные вызовы:

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

Теперь, поскольку это определяет переменную documents только после получения результатов, вам необходимо предварительно инициализировать переменную documents в области: $scope.documents = []. В противном случае ваш ng-repeat задохнется.

Таким образом, ng-repeat сначала вернет пустой список, потому что массив documents сначала пуст, но как только будут получены результаты, ng-repeat снова запустится, потому что "документы" были изменены в успешный обратный вызов.

Кроме того, вы можете изменить выражение ng-repeat на:

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

потому что если ваша функция DisplayDocuments() делает вызов на сервер, этот вызов будет выполняться много раз, из-за циклов $digest.

Ответ 2

Обещание, возвращенное из $http, не может быть привязано напрямую (я точно не знаю почему). Я использую службу обертывания, которая отлично работает для меня:

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

и привязать его к контроллеру:

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

UPDATE:

В Angular было удалено 1.2 авторазвертывание promises. См. http://docs.angularjs.org/guide/migration#templates-no-longer-automatically-unwrap-promises

Ответ 3

На самом деле вы получаете promise на $http.get.

Попробуйте использовать следующий поток:

<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 - ваш массив.

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

Ответ 4

Попробуйте использовать обратный вызов success()

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

Но теперь, поскольку Documents является массивом, а не обещанием, удалите ()

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