0

当前应用程序 - 带有 Breeze 的 Angular 应用程序。应用程序有大约 7 个实体管理器和不同的数据域(元数据)。当应用程序运行时,我们尝试获取实体管理器,例如:

app.run(['$rootScope', 'datacontext1', ... ], function($rootScope, datacontext1, ...) {
   datacontext1.loadMetadata();
...
   datacontext7.loadMetadata();
}

每个数据上下文都有自己的实体管理器,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 将承诺解析为“已获取”,在这种情况下 applyCustomMetadata() 操作无法执行。

据我了解,问题出在 Breeze 内部,并使用它来解决元数据承诺(似乎是 http 适配器是单例的,第二个请求使用“已获取”字符串覆盖元数据,并且 applyCustomMetadata() 操作永远不会执行)。

需要找出一些方法来解决问题,而无需对应用程序进行重大更改。

在 loadMetadata 完成时,逻辑上需要延迟整个应用程序使用实体管理器。寻找 Breeze 级别的任何方法来禁用自动获取元数据,如果它已经在进行中(但不是中断请求,只需等待一段时间后重试)。任何其他想法也很好。

4

1 回答 1

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

于 2016-01-22T22:55:33.130 回答