当前应用程序 - 使用Breeze的Angular应用程序。应用程序有~7个实体管理器和不同的数据域(元数据)。当应用程序运行时,我们尝试获取实体管理器,例如:
app.run(['$rootScope', 'datacontext1', ... ], function($rootScope, datacontext1, ...) {
datacontext1.loadMetadata();
...
datacontext7.loadMetadata();
}
每个datacontext都有自己的实体管理器,loadMetadata是:
function loadMetadata() {
manager.fetchMetadata().then(function(mdata) {
if (mdata === 'already fetched') {
return;
}
...
applyCustomMetadata(); // Do some custom job with metadata/entity types
});
}
元数据来自服务器异步。很少有模块具有非常大的元数据,例如200Kb,并且需要一些时间来加载并应用于实体管理器。可能会在此loadMetadata操作完成之前启动在同一实体管理器中执行的第一个Breeze数据请求,据我所知,Breeze会自动再次获取元数据。通常它不是问题,元数据端点缓存在服务器上,但有时它会产生非常奇怪的Breeze行为 - EntityManager.fetchMetadata解析promise#34;已经取出"在这种情况下,applyCustomMetadata()操作无法执行。
据我所知,问题出在Breeze中并且接近其用于解析元数据的承诺(似乎是http适配器是单例,第二个请求覆盖元数据用"已经取出"字符串和applyCustomMetadata()操作永远不会执行)
需要找出解决问题的方法,而不会在应用程序中发生重大变化。
逻辑上需要在loadMetadata完成时延迟使用实体管理器的完整应用程序。在Breeze级别上寻找任何方式来禁用自动提取元数据(如果它已经在进行中)(但不是中断请求,只需等待一段时间后重试)。任何其他想法都很好。
答案 0 :(得分:0)
为什么在加载元数据之前允许执行查询?这就是你的问题。
我有一个应用程序引导程序,我通过全局变量公开;在初步过程完成之前,我的应用程序活动都不会启动,具体取决于实体管理器:
var bootstrapper = {
pageReady: ko.observable(false)
};
initBootstrapper();
return bootstrapper;
function initBootstrapper() {
window.MyApp.entityManagerProvider.initialize() // load metadata, lookups, etc
.then(function () {
window.MyApp.router.initialize(); // setup page routes, home ViewModel, etc
bootstrapper.pageReady(true); // show homepage
});
};
此外,根据组织中发生的数据库更改频率,您可能希望在page_load上同步将元数据传递到客户端。有关详细信息,请参阅此文档:
http://breeze.github.io/doc-js/metadata-load-from-script.html