【问题标题】:Angularjs $http.get().then and binding to a listAngularjs $http.get().then 并绑定到一个列表
【发布时间】:2013-05-27 04:32:51
【问题描述】:

我有一个如下所示的列表:

<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 方法时,我得到三个空行,使计数正常,但没有显示任何信息。

我知道“一切”都可以,因为我之前用 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,…}

【问题讨论】:

  • 我通常使用 .get(...).success(function (data) {});也许您可以添加 console.log(result) 并查看它的输出?我还要确保您调用的网址格式正确。什么是caseId?
  • 我也试过了,只是觉得这看起来更好,而且更容易理解,这就是我想试一试的原因。我见过有人同时使用这两种方法,但无法以这种方式工作。
  • 您将Document 绑定到您的范围,但在ng-repeat 中使用DisplayDocuments() DisplayDocuments() 来自哪里?
  • 我在工厂做类似的事情。但是,我有 var mypromise 而不是 $scope.Documents,我在 then/success 部分设置了 $scope.Documents
  • 我有一个应该返回文档的服务,这就是为什么我想避免在 then/success 部分设置 $scope.documents,但看起来我必须这样做。

标签: angularjs get promise


【解决方案1】:

$http 方法返回一个 promise,它不能被迭代,所以你必须通过回调将结果附加到范围变量:

$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 会再次运行,因为 `documents` 在成功回调。

此外,您可能希望将 ng-repeat 表达式更改为:

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

因为如果您的 DisplayDocuments() 函数正在调用服务器,那么由于 $digest 循环,该调用将被多次执行。

【讨论】:

  • 所以我只能在不返回数组的情况下返回对范围的承诺? Displaydocuments 不会调用服务器,无论如何感谢您的提醒。
  • 我的意思是,如果你写 $scope.documents = $http.get(...)documents 将引用一个承诺(来自 $q 服务),因为这是 $http 服务返回的,一个承诺。
  • 是的,明白这一点,但我认为 Angular 能够自动解决这个承诺?显然我错了。
  • 您可能将 $http 服务误认为$resource,它确实返回了一个(迭代)promise,但是当返回结果时,promise 会自动解决。
  • 老实说不知道 $resource,但它看起来和我要找的完全一样。谢谢!
【解决方案2】:

$http 返回的Promise 不能直接绑定(我不知道为什么)。 我正在使用非常适合我的包装服务:

.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;
    ...
}

更新!

在 Angular 1.2 中,自动解包承诺已被删除。 见http://docs.angularjs.org/guide/migration#templates-no-longer-automatically-unwrap-promises

【讨论】:

  • 我仍然不太确定如何,但是伙计,你已经结束了我的痛苦。谢谢!
  • @Davion 和其他想知道这段代码发生了什么的人, $http 返回一个包装响应对象的 http 承诺,而不是实际数据。这就是为什么你不能直接“绑定”到它。在这里,$q 服务被用于创建一个新的 Promise,该 Promise 被解析为实际数据。使用该承诺,控制器可以获取实际数据,而不仅仅是 http 响应。顺便说一句,不推荐使用 $http successerror 方法,因此现在建议使用 then
【解决方案3】:

实际上你在$http.get 上得到promise

尝试使用跟随流程:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2010-11-07
      • 2017-05-15
      • 2016-04-03
      相关资源
      最近更新 更多