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,…}
Ответы
Ответ 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>