$资源承诺是否应该与$ q兼容?也许我错了。我有两个$ resource对象,我可能会加载:
$rootScope.foos = Res1.query(); // [ foo1, foo2...]
$rootScope.bars = Res2.query(); // [ bar1, bar2...]
当两个(并且只有两个)查询到达时,我需要广播一个事件。所以我正在使用$ q.all这样:
$q.all([$rootScope.foos.$promise, $rootScope.bars.$promise])
.then(function(){
// sometimes $rootScope.bars == []
$rootScope.$broadcast('foos_and_bars!');
});
事件监听器发现$ rootScope.bars为空/ []
(一秒后它有数据)
响应@Daiwei 和@ExpertSystem
进行更新好的,这是JSFiddle: Reproducing JSFiddle
控制台显示在解决promise之前返回$ q.all()。我想要么它被错误使用,或者它是一个与[$ resource,$ scope,$ http等]中的任何一个有关的角色错误......
答案 0 :(得分:2)
原来是版本冲突问题。 下面提供的解决方案是使用更高版本(使用1.2.8测试),但完全是多余的 有关详细信息,请参阅 Purrell's answer 。
在 $resource
:
重要的是要意识到调用$ resource对象方法会立即返回一个空引用(取决于isArray的对象或数组)。从服务器返回数据后,将使用实际数据填充现有引用。这是一个有用的技巧,因为通常将资源分配给模型,然后由视图呈现。具有空对象导致无渲染,一旦数据从服务器到达,则对象用数据填充,并且视图自动重新呈现其自身显示新数据。这意味着在大多数情况下,永远不必为动作方法编写回调函数 [...]
资源实例和集合具有以下附加属性:
- $ promise:...
- $已解决:......
您的Res1
和Res2
是$ resource 对象(不是实例)和(根据文档)调用{{1} } method “立即返回一个空引用”(在你的情况下是一个数组)。 ( UPD :但返回的数组仍然具有其他属性。)
正如文档建议的那样,大多数情况下,您只是将这些空引用分配给Scope并忘记它们(一旦获取数据,模型(以及随后的视图)将自动更新)。
然而,如果您确实有理由希望在数据出现后立即获得明确通知,您可以使用两个“真正的”承诺:
query()
另请参阅此 working example 。
<强>更新强>
由于返回的数组也具有// Create two deferred objects
var deferred1 = $q.defer();
var deferred2 = $q.defer();
// As soon as the data arrives, resolve the deferred objects
$rootScope.foos = Res1.query(function () { deferred1.resolve(); });
$rootScope.bars = Res2.query(function () { deferred2.resolve(); });
// Combine their promises using `$q.all()`
$q.all([deferred1.promise, deferred2.promise]).then(...);
属性,因此更简洁的版本是:
$promise
<强> Working demo 强>
答案 1 :(得分:1)
这结果是ngResource和angular之间的意外版本冲突。 Angular是1.2.6,但ngResource是1.2.3。
最初发布的小提琴不适用于类似但不同的ngResource版本问题,即它使用的是一个旧的ngResource版本,它没有用来公开$ promise对象(虽然它们仍在引擎盖下使用)。在ngResource的更高版本中,承诺被公开,因此它们可以用于这样的事情。
@ ExpertSystem的建议很好,但不会解决问题。我之前尝试使用$ q.defer()promises,当出现版本冲突时它也有同样的问题。 在没有版本冲突的情况下工作,但是这是不必要的,当它们已经为您提供方便时,不需要创建自己的承诺。
这是working JSFiddle(angular 1.2.1
,但对于ngResource来说已经足够了)
答案 2 :(得分:0)
你的$ q.all()之后...你可以使用.spread(函数(prom1,prom2){}代替所有promises返回时运行。按照你现在的方式执行它.then会触发每当数组中的一个项返回时,为什么有时候数组中的一个项是空的。