以$路线的决心解决微风查询/ Q承诺停止页 [英] Resolving breeze query/Q promise with $route resolve stops page
问题描述
我在执行与棱角分明的决心轻而易举查询视图显示以前的问题。我试图从服务器获取一些数据前视图与渲染的微风。我使用
I'm having problems executing a breeze query with angular resolve before the view is rendered. I'm trying to get some data from the server before the view is rendered with breeze. I'm using
$routeProvider.when('/countries', { templateUrl: 'App/partials/countries.html', controller: Ctrl, resolve: Ctrl.resolve }).
控制器和服务片段:
controller and service snippets:
function Ctrl($scope, Q, datacontext, countries) {
//...
}
function getCountries(forceRefresh) {
var query = entityQuery.
from("countries").
orderBy("name");
return manager.executeQuery(query).
then(getSucceeded);
}
function getSucceeded(data) {
return data.results;
}
这使得我的观点从来没有渲染:
this makes my view never render:
Ctrl.resolve = {
countries: function (datacontext) {
return datacontext.getCountries();
}
}
而如果我创建了一个计时器,需要较长的时间,它的工作原理。我试着用$ Q包装,但我似乎无法得到它的工作。
whereas if I create a timer that takes longer time, it works. I've tried wrapping it with $q but I can't seem to get it to work.
这会使,因为超时的观点:
this will render the view because of the timeout:
Ctrl.resolve = {
countries: function (datacontext) {
return datacontext.getCountries();
},
delay: function ($q, $timeout) {
var delay = $q.defer();
$timeout(delay.resolve, 6000);
return delay.promise;
}
}
如果任何人都可以帮助我,这将是巨大的。我不知道如果我做错了什么,或者有与决心Q承诺或微风的限制。
If anyone can help me with this, it would be great. I'm not sure if I'm doing something wrong or if there are limitations with Q promises or breeze in resolve.
推荐答案
我觉得你的痛苦。一个在$ Q /路由解决执行中的错误是,决心不履行 Q.then
方法。违反支持互换的承诺实现(叹气)普遍接受的做法。
I feel your pain. One of the mistakes in the $q/route resolve implementation is that the resolve does not honor the Q.then
method. That violates the generally accepted practice of supporting interchangeable promise implementations (sigh).
但是,这不是真正的问题。真正的问题是,当你的异步方法解析角不知道。你必须手动调用 $ rootScope。$适用
在成功和失败的回调。角的$ http和$ Q为你做这个(或同等学历)。得到它的权利是自己皮塔。
But that's not the real problem. The real problem is that Angular doesn't know when your async method is resolved. You have to call $rootScope.$apply
manually in both success and failure callbacks. Angular's $http and $q do this (or equivalent) for you. Getting it right yourself is a PITA.
正如我所说的,我们觉得你的痛苦。很快可以转换问答承诺$ Q承诺,应减轻痛苦,我们会发布一个小小的中的Q插件。至少它为我: - )
As I said, we feel your pain. Very soon we will release a tiny Q plug-in that converts a Q promise to $q promise and should alleviate that pain. At least it does for me :-).
在简单地说,发现不远的地方你的应用程序开始的地方,并延长Q是这样的:
In a nutshell, find a place near where your app starts and extend Q something like this:
angular.module('app').factory('util', ['$q', '$rootScope', util]);
function util($q, $rootScope) {
extendQ();
... other utilities here ...
// Monkey patch to$q method into Q.js' promise prototype
// ex usage: return manager.executeQuery(qry).to$q(succ, fail);
function extendQ() {
var promise = Q.defer().promise;
var fn = Object.getPrototypeOf(promise);
if (fn.to$q) return; // already extended
fn.to$q = function (success, fail) {
return to$q(this, success, fail);
};
}
function to$q(qPromise, success, fail) {
var d = $q.defer();
qPromise
.then(function (data) {
if (data === undefined) {
logger.logError("Programming error: no data. " +
"Perhaps success callback didn't return a value or " +
"fail callback didn't re-throw error");
// If an error is caught and not re-thrown in an earlier promise chain
// you will arrive here with data === undefined.
// Neglecting to re-throw is a common, accidental omission.
// To be safe, have every success callback return something
// and trap here if data is ever undefined
}
d.resolve(data);
$rootScope.$apply();// see https://groups.google.com/forum/#!topic/angular/LQoBCQ-V_tM
})
.fail(function (error) {
d.reject(error);
$rootScope.$apply();// see https://groups.google.com/forum/#!topic/angular/LQoBCQ-V_tM
});
if (success || fail) {
d.promise = d.promise.then(success, fail);
}
return d.promise;
}
现在这样使用它(根据你的例子):
Now use it like this (based on your example):
function getCountries() {
var query = breeze.EntityQuery.from("countries").orderBy("name");
return manager.executeQuery(query).to$q(getSucceeded);
function getSucceeded(data) { return data.results; }
}
附录
我一直在问:
的为什么这么复杂?你为什么不使用 $ q.when(qPromse)
转换Q承诺$ Q承诺?的
"Why so complicated? Why don't you use $q.when(qPromse)
to convert Q promise to $q promise?"
我试过了...并不能使它发挥作用。具体来说,我尝试这样做:
I tried that ... and couldn't make it work. Specifically, I tried this:
function to$q(qPromise, success, fail) {
var promise = $q.when(qPromise);
if (success || fail) {
promise = promise.then(success, fail);
}
return promise;
}
我相信是有什么毛病 $ q.when
。
这篇关于以$路线的决心解决微风查询/ Q承诺停止页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!