Jur*_*hen 8 promise typescript breeze ecmascript-6 angular
我正在尝试学习angular2并使用odata webapi后端创建了一个测试应用程序.在应用程序中,我有一个视图,它获取一个项目数组,我想在我的视图中显示这些.
为了从前端获取数据我正在使用breezejs库,因为它已经证明在过去节省了我很多时间,我喜欢将它与odata后端一起使用.
调用树和应用程序结构如下所示:
通过从视图中调用服务函数开始调用以开始获取项目(请注意,我将从每次调用返回es-6承诺):
this._scrumModuleService.fetchActiveSessions().then((sessions: ScrumSession[]) => {
// Here i have to call zone.run else my view wont update.
this._zone.run(() => {
this.sessions = sessions;
});
}).catch((error: any) => {
debugger;
});
Run Code Online (Sandbox Code Playgroud)
然后从视图中它将转到服务,该服务又调用存储库:
public fetchActiveSessions(): Promise<ScrumSession[]> {
return this._scrumSessionRepository.fetchActiveSessions();
}
Run Code Online (Sandbox Code Playgroud)
存储库获取功能:
public fetchActiveSessions(): Promise<ScrumSession[]> {
return this._dataContext.fetch(new breeze.EntityQuery().from("ScrumSessions").expand(['creator', 'scrumRoom','productOwner', 'users']));
}
Run Code Online (Sandbox Code Playgroud)
然后最终存储库调用(通用)datacontext,它将使用breeze entitymanager执行查询:
public fetch(query: breeze.EntityQuery, isRetry: boolean = false): Promise<any> {
return new Promise((resolve, reject) => {
this.entityManager.executeQuery(query).then((result: breeze.QueryResult): void => {
// Data has been fetched, resolve the results
resolve(result.results);
});
});
}
Run Code Online (Sandbox Code Playgroud)
现在你可以在视图中看到我必须使用NgZone的run函数,否则我的视图不会更新.我想知道为什么我必须这样做,因为我期待angular2自动为我看到这个.我已经挖掘了几个类似的问题,但还没找到答案.我还包括了另一个线程中建议的angular2-polyfills脚本,但是没有解决它.
我缺少什么或者我必须实现什么才能在不调用zone.run的情况下自动更新视图?
现在,Breeze和Angular2运行得很好.我们正在使用当前版本的Breeze和Angular Beta 8开发一个大型应用程序,没有任何问题.
目前唯一的轻微解决方法是微风还没有使用Angular2 http提供程序.但是,您可以在默认的"Q"提供程序中进行填充,以便它支持Angular2期望的ES6 Promises,其代码如下:
/**
* Minimum necessary deferred object for breeze Q/ES6 Promise adapter
* Makes ES6 promise look like Q.
*/
export interface Deferred {
promise: Promise<any>;
resolve: (value?: {} | PromiseLike<{}>) => void;
reject: (reason?: any) => void;
}
/**
* Minimum for breeze breeze Q/ES6 Promise adapter
*/
export const Q = {
defer(): Deferred {
let resolve: (value?: {} | PromiseLike<{}>) => void;
let reject: (reason?: any) => void;
let promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
})
return {
promise: promise,
resolve(value: any) { resolve(value); },
reject(reason: any) { reject(reason); }
}
},
resolve(value?: {} | PromiseLike<{}>) {
let deferred: Deferred = Q['defer']();
deferred.resolve(value);
return deferred.promise;
},
reject(reason?: any) {
let deferred: Deferred = Q['defer']();
deferred.reject(reason);
return deferred.promise;
}
}Run Code Online (Sandbox Code Playgroud)
然后,您可以导入此文件
import { Q } from './q';
然后在你的应用程序顶部附近的某个地方
breeze.config.setQ(<breeze.promises.IPromiseService>Q);
此时,所有标准微风方法都与现在完全一样,Angular的变化检测也应该没有问题.
Angular 运行在大多数异步 API 都已修补的区域中。当异步调用完成时,Angular 会运行更改检测。
不知何故,微风代码离开了 Angulars 区域并“破坏”了变更检测。这要么是因为您从 Angular 外部初始化 Breeze,要么是 Breeze 使用了一些未由 Angulars 区域修补的异步 API,因此回调是在 Angulars 区域外执行的。