2014-12-05 58 views
0

我建立了一个名为“Data”的工厂。我可以在控制器如下使用:

控制器

myApp.controller('MyController', ['$scope', '$firebase', 'Data', function($scope, $firebase, Data) { 

// OTHER REFS/FIREBASE 

$scope.entries = Data; 

}]); 

的index.html

<div ng-repeat="entry in entries"> 
{{entry.name}} 
</div> 

工厂

myApp.factory('Data', ['$http', function ($http) { 

    // load the data 
    var entriesz = []; 
    $http.get('data/main.json').success(function(data) { 
     angular.forEach(data.ParkingFacilities, function(entry) { 
     $http.get(entry.staticDataUrl).success(function(data) { 
      entriesz.push(angular.extend(entry, data.parkingFacilityInformation)); 
     }); 
     }); 
    }); 

    //window.alert("Data Imported :" + entriesz.length); 
    //window.alert(JSON.stringify(entriesz)) 

    return entriesz; 
    // parse it and store it on firebase 

}]); 

我现在想知道如何使用此工厂在我的Firebase存储中更新它,并创建可访问此存储数据的附加控制器。

P.s.如果您想知道为什么我不使用上述示例中的工厂,基本上,检索数据需要很多计算时间,所以为了节省一些计算时间,我想分割后端和前端进程。

+1

请编辑博文,包括数据的工厂代码,在至少可以让我们理解你的问题的最小部分。 – 2014-12-05 16:23:57

+0

包括工厂。使用entriesz有很多困难... typeof是未定义的,数组的长度显然为0.但是,当我放入$ scope.entries = entriesz,然后返回到我的index.html并写入{{条目[0]}}然后它显示在我的第一个数组项目中的对象。但似乎在控制器entriesz [0]不起作用......这很奇怪! – JohnAndrews 2014-12-05 16:28:36

回答

2

这是很难说肯定,但它似乎是你被异步性质$http.get咬伤。

让我们简化代码了一下,这样的:

/* 1 */ var entriesz = []; 
/* 2 */ $http.get('data/main.json').success(function(data) { 
/* 3 */ angular.forEach(data.ParkingFacilities, function(entry) { 
/* 4 */  $http.get(entry.staticDataUrl).success(function(data) { 
/* 5 */   entriesz.push(angular.extend(entry, data.parkingFacilityInformation)); 
/* 6 */  }); 
/* 7 */ }); 
/* 8 */ }); 
/* 9 */ window.alert("Data Imported :" + entriesz.length); 

我已经编号的线,所以我们可以参考他们更容易。

你似乎认为这段代码是线性执行的,所以第1行,第2行,第3行......第9行。但那不是什么情况。这些$http.get调用中的每一个都开始从远程服务器下载数据。由于这可能需要一段时间,浏览器不会等待数据回来。它只是继续执行其余的代码。然后,当来自服务器的响应回来时,它会执行您传入success的回调函数。

因此,您的代码更可能的执行顺序是:1,2,9 ...等待main.json ... 3,4 ...等待数据.... 5,3,4 ...等待数据... 5等。知道这一点,您可能会明白为什么entriesz.length在第9行显示为0:当您发出警报时,条目尚未加载。

这是比较容易看到,如果你把那些匿名函数退出该流程,并给他们这样的名字:

var entriesz = []; 
$http.get('data/main.json').success(onMainJsonLoaded); 
window.alert("Data Imported :" + entriesz.length); 

function onMainJsonLoaded(data) { 
    angular.forEach(data.ParkingFacilities, function(entry) { 
    $http.get(entry.staticDataUrl).success(onStaticDataLoaded); 
    } 
} 

function onStaticDataLoaded(data) { 
    entriesz.push(angular.extend(entry, data.parkingFacilityInformation)); 
    window.alert("Partial data imported :" + entriesz.length); 
} 

这异步加载是现代网络的完全正常的一部分,但高度反对于那些新手来说很直观。试图绕过它可能是你自然的本能,但我强烈建议你不要尝试这个,而应该接受它。你不能让网络同步(如果可能的话,任何人都不会高兴),所以你最好的办法就是学会处理它的异步特性。

在这种情况下,您可以通过在数据可用时更新UI来实现此目的。例如:我在上面的onStaticDataLoaded函数中添加了一个警报,以显示当时您的部分数据已经可用。这将是更新网页中“{{}}项目已加载”指标的完美时间。


我试着在上述问题的上下文中解释问题。但是对于类似的问题,还有很多(可能更好)的答案。其中一些可能是值得你花时间,所以我会一一列举:

+0

再次感谢您。尝试过你的例子,但仍然无法正常工作。它再次返回长度等于0,也似乎不进入onStaticDataLoaded函数。我添加了insMonJsonLoaded(数据)函数entriesz.lengths并且它又一次返回Undefined ... – JohnAndrews 2014-12-06 10:27:45

+0

这就是我的main.json的样子:https://npropendata.rdw.nl/parkingdata/v2/ 和staticDataUrls:https://npropendata.rdw.nl/parkingdata/v2/static/d8f4e169-b645-40e8-bb53-394d50d46a69 – JohnAndrews 2014-12-06 10:28:27

+1

我的代码片段没有'return'语句。如果仍然存在,那么在从服务器返回数据之前,您仍有机会返回。更新您的问题以包含新的片段。请删除与问题无关的任何内容,就像我在上面编写代码片段时所做的一样。 – 2014-12-06 13:34:57

相关问题