Angular.js - 来自AJAX请求的数据作为ng-repeat集合

时间:2013-08-30 12:37:34

标签: ajax angularjs angularjs-ng-repeat

在我的网络应用程序中,我每隔3-4秒从AJAX调用API返回数据,如下所示:

$http.get('api/invoice/collecting').success(function(data) {
    $scope.invoices = data
}

然后显示数据,如下所示:http://jsfiddle.net/geUe2/1/

问题是我每次$scope.invoices = data ng-repeat重建jsfiddle中显示的DOM区域,我会丢失所有<input>值。

我试过:

  • angular.extend()
  • jQuery.extend
  • 的深层版本
  • 其他一些合并\ extends \ deep复制功能

但他们无法处理这样的情况:

在我的客户端上有[invoice1, invoice2, invoice3],服务器发送给我[invoice1, invoice3]。所以我需要从视图中删除invoice2。

有什么方法可以解决这个问题?

3 个答案:

答案 0 :(得分:1)

查看ng-repeat文档Angular.js - Data from AJAX request as a ng-repeat collection 您可以使用track by选项:

  通过tracking_expression

表达式跟踪中的变量 - 您还可以提供可选的跟踪功能,该功能可用于将集合中的对象与DOM元素相关联。如果未指定跟踪功能,则ng-repeat按集合中的标识关联元素。使用多个跟踪功能解析为同一个密钥是错误的。 (这意味着两个不同的对象被映射到同一个DOM元素,这是不可能的。)在指定跟踪表达式之前,应将过滤器应用于表达式。

     

例如:item by项目中的项目是项目来自数据库时的典型模式。在这种情况下,对象标识无关紧要。只要两个对象的id属性相同,它们就被认为是等价的。

答案 1 :(得分:0)

当服务器的更新到达时,您需要从DOM收集数据。保存任何相关的数据(它可能只是输入值),并且不要忘记包含数据对象的标识符,例如data._id。所有这些都应保存在$scope.oldInvoices等临时对象中。

然后在从DOM收集它之后,使用新数据(您现在正在进行的方式)重新更新DOM $scope.invoices = data。 现在,使用 underscore.js _.findWhere 来确定您的data._id是否存在于新数据更新中,如果是,请重新分配(您可以在此使用Angular.extend)您保存到相关发票的数据值

答案 2 :(得分:0)

出来了,@ luacassus关于track by指令ng-repeat选项的回答非常有帮助,但没有解决我的问题。 track by功能正在添加来自服务器的新发票,但是发生了清除非活动发票的一些问题。 所以,这是我对问题的解决方案:

function change(scope, newData) {
    if (!scope.invoices) {
        scope.invoices = [];
        jQuery.extend(true, scope.invoices, newData)
    }
    // Search and update from server invoices that are presented in scope.invoices
    for( var i = 0; i < scope.invoices.length; i++){
        var isInvoiceFound = false;
        for( var j = 0; j < newData.length; j++) {
            if( scope.invoices[i] && scope.invoices[i].id && scope.invoices[i].id == newData[j].id ) {
                isInvoiceFound = true;
                jQuery.extend(true, scope.invoices[i], newData[j])
            }
        }
        if( !isInvoiceFound ) scope.invoices.splice(i, 1);
    }
    // Search and add invoices that came form server, but are nor presented in scope.invoices
    for( var j = 0; j <  newData.length; j++){
        var isInvoiceFound = false;
        for( var i = 0; i < scope.invoices.length; i++) {
            if( scope.invoices[i] && scope.invoices[i].id && scope.invoices[i].id == newData[j].id ) {
                isInvoiceFound = true;
            }
        }
        if( !isInvoiceFound ) scope.invoices.push(newData[j]);
    }

}

在我的网络应用中,我使用的是jQuery&#39; .extend()lo-dash库中有一些不错的选择。