4

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

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

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

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

我试过这样做:

  • angular.extend()
  • 深版的jQuery.extend
  • 其他一些合并\扩展\深拷贝功能

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

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

有哪些方法可以解决这个问题?

4

3 回答 3

1

检查ng-repeat文档Angular.js - 来自 AJAX 请求的数据作为 ng-repeat 集合 您可以使用track by选项:

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

例如:item in items track by item.id 是当项目来自数据库时的典型模式。在这种情况下,对象身份无关紧要。只要 id 属性相同,两个对象就被认为是等价的。

于 2013-08-30T14:06:52.963 回答
0

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

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

于 2013-08-30T13:55:50.407 回答
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 的.extend(). lo-dash库中有一些不错的选择。

于 2013-10-19T06:45:06.603 回答