在我的网络应用程序中,我每隔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
但他们无法处理这样的情况:
在我的客户端上有[invoice1, invoice2, invoice3]
,服务器发送给我[invoice1, invoice3]
。所以我需要从视图中删除invoice2。
有什么方法可以解决这个问题?
答案 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库中有一些不错的选择。