Breezejs,如何在开始时使用共享的EntityManager获取元数据

时间:2013-04-17 19:09:18

标签: angularjs breeze

我有一个使用Breeze的Angular应用程序,它有一个共享的EntityManager用于我的不同控制器。可以在不执行查询的情况下访问我的一些控制器,以预先填充EntityManager的MetadataStore。我发现了一些起始方向here说要在应用程序开始时获取元数据。我的项目基于Angular-Breezejs模板,当我尝试执行以下操作时,我会收到错误,因为在使用datacontext之前,promise没有完全解析。

app.factory('datacontext',
    ['breeze', 'Q', 'model', 'logger', '$timeout',
        function (breeze, Q, model, logger, $timeout) {
            logger.log("creating datacontext");

            configureBreeze();
            var manager = new breeze.EntityManager("/api/app");            
            manager.enableSaveQueuing(true);

            var datacontext = {
                metadataStore: manager.metadataStore,
                saveEntity: saveEntity,
                getUsers: getUsers,
                getUser: getUser,
                createUser: createUser,
                deleteUser: deleteUser
            };

            return manager.fetchMetadata()
                    .then(function () {
                        model.initialize(datacontext);
                        return datacontext;
                    })
                    .fail(function (error) {
                        console.log(error);
                        return error;
                    });
            //Function definitions

在元数据提取完成之前,阻止的正确方法是什么?因为似乎没有必要在每个非查询函数(包括实体创建)之前检查元数据是否存在,就像上面链接问题的原始海报一样。

1 个答案:

答案 0 :(得分:11)

我看到了你的问题。

当Angular调用您的工厂函数来创建DataContext服务时,它希望立即(同步)返回准备使用的DataContext对象。但是你将在未来的某个时间返回一个 promise 来返回DataContext ...并且Angular就不是为此而构建的。

  

我喜欢这个主意。你可能想把它提交给Angular团队:-)。

所以你在这里尝试的东西是行不通的。您必须立即返回DataContext。在元数据到达之前,您必须阻止整个UI或阻止依赖于元数据的特定功能(例如,createUser)。这有点像在使用jQuery操作它之前等待DOM安定下来。

  

这种情况不是特定角度的。你在Knockout应用程序中面临同样的困境。决议是类似的。

首先在DataContext上公开某种“whenReady”挂钩。承诺可能是一个好主意。像这样:

function (breeze, Q, model, logger, $timeout) {
    logger.log("creating datacontext");
    ...
    var readyDeferred = Q.defer(), whenReady = readyDeferred.promise;

    var datacontext = {
            whenReady: whenReady,
            ...
        };

    initializeDatacontext();

    return datacontext; // now Angular is happy because it has a datacontext

    function initializeDatacontext() {
        manager.fetchMetadata()
               .then(function () {
                   readyDeferred.resolve();
                   // do success stuff;
               })
               .fail(function (error) {
                   readyDeferred.reject(error);
                   // do error stuff;
               });
    }

    //Function definitions
}

在您的应用程序引导的其他地方,您可以加入datacontext.whenReady承诺。

    // somewhere inside your main controller
    $scope.isReady = false;
    datacontext.whenReady.then(function() {
           $scope.isReady = true;
           $scope.$apply();
       })
    .fail(function() { alert("Uh oh!"); });
    ...

现在将范围的isReady绑定到HTML,以便获得所需的行为。您可以使用它来阻止整个UI或仅封锁功能(例如,“创建用户”),直到datacontext准备就绪。

请勿按字面意思使用此伪代码。用它来获取灵感。