2

我正在尝试让 Breeze.JS 使用 angular 的 http 服务进行 ajax 调用。我遵循了文档(http://www.breezejs.com/documentation/customizing-ajax)并应用了它。但是它不起作用。

此外,当我检查微风源代码时,我看到以下内容:

fn.executeQuery = function (mappingContext) {

    var deferred = Q.defer();
    var url = mappingContext.getUrl();

    OData.read({
            requestUri: url,
            headers: { "DataServiceVersion": "2.0" }
        },
        function (data, response) {
            var inlineCount;
            if (data.__count) {
                // OData can return data.__count as a string
                inlineCount = parseInt(data.__count, 10);
            }
            return deferred.resolve({ results: data.results, inlineCount: inlineCount });
        },
        function (error) {
            return deferred.reject(createError(error, url));
        }
    );
    return deferred.promise;
};

它只是调用 OData.read 而不对 http 服务做任何事情。因此 OData 使用了内置的 ajax。我不明白上面的代码,如何自定义 Breeeze.JS 的 ajax

4

2 回答 2

3

问题是 Breeze OData 路径不使用 Breeze Ajax 适配器。更改 Breeze Ajax 适配器(如“Breeze Angular 服务”所做的那样)将无济于事。

目前,“OData”和“webApiOData”DataService 适配器都委托给第 3 方datajs库以提供 AJAX 服务(以及其他与 OData 相关的支持)。

您可以将其替换odata.defaultHttpClient为您自己的基于$http. 这不是一项微不足道的任务。在此处查找源代码;大约有 160 行。

我想我们可以写一个。这不是一个优先事项。

直到有人这样做或者我们放弃datajs(如果有的话,不会很快),你会被datajs ajax 困住。

对于那个很抱歉。

ps 几乎所有与 OData 数据源交谈的人都使用datajs库。也许您可以与该库的作者交谈并尝试让他们支持$http.

于 2014-03-17T07:12:29.383 回答
1

快速而肮脏的 hack 来模拟 $http 服务

我今天遇到了这个问题。由于使用了外部 datajs AJAX 方法而不是 Angular 的$http服务(正如 Ward 所解释的),Breeze 查询不会触发摘要,模型也不会更新。

与任何外部到角度的更改一样,简单的解决方案是将查询中的任何分配包装在一个$scope.$apply()函数中。但是,这会很快使您的应用程序混乱,因此这是一个坏主意。

我想出了一个快速而肮脏的技巧,到目前为止似乎效果很好:

  1. 我有一个dataContext服务,它封装了我所有的 Breeze 查询并公开了诸如等方法getCustomers()getProducts()灵感来自Breeze 站点上的示例)。
  2. 当这些数据访问方法中的任何一个完成时(即 promise 解析),我调用一个triggerAngularDigest()方法。
  3. 此方法$rootScope.$apply()$timeout().
  4. 导致 Angular 在下一个滴答时运行摘要,$timeout()即在您的 Breeze 查询中的数据已分配给您的模型之后。
  5. 您的所有模型都会像使用时一样更新$http,无需调用$apply()您的控制器。

简化版:

function dataContext($rootScope, $timeout, breeze) {

    // config of entity manager etc snipped

    return {
        getCustomers: function () {
            return breeze.EntityQuery.from('Customers')
                .using(manager)
                .execute()
                .then(function(data) {
                    triggerAngularDigest(); // <-- this is the key
                    return data;
                });
        }
    };

    function triggerAngularDigest() {
        $timeout(function() {
            $rootScope.$apply();
        }, 0);
    }
}

myApp.factory('dataContext', dataContext);

然后:

// some controller in your app
dataContext.getCustomers().then(function(data) {
    scope.customers = data;
}); 
于 2014-11-07T13:55:55.497 回答