BreezeJS datacontext POST角度变为'GET'

时间:2014-12-08 18:04:02

标签: angularjs post breeze

我有一个工厂通过POST从我自己的服务器检索json,我得到了错误" TypeError:无法读取属性' $ http'未定义{query:ctor,stack:(...),message:"无法读取属性' $ http'未定义"}"。走过breeze.debug.js我看到我的请求变成了一个GET,从而打开了电话。我如何强制Breeze执行我的POST?以下是基于关于在http://www.getbreezenow.com/documentation/breezeajaxpostjs发布帖子的BreezeJS文档的datacontext:

angular.module('rmBreezeApp.datacontext', [])

.factory('datacontext', function ($http, breeze, jsonResultsAdapter, logger, model, RMServer,AuthService) {
    breeze.ajaxpost();

    var postData = function (selector, argsArray) {
        return   {"selector": selector, "arguments": argsArray}
    };

    var ds = new breeze.DataService({
        serviceName: RMServer,
        hasServerMetadata: false,
        useJsonp: false,
        jsonResultsAdapter: jsonResultsAdapter
    });

    var manager = new breeze.EntityManager({dataService: ds});

    model.initialize(manager.metadataStore);

    return {
        getShiftsForWeek: getShiftsForWeek
    };

    /*** implementation details ***/
    function getShiftsForWeek() {
        var arguments = [];

        var query = breeze.EntityQuery.from("session?token=" + AuthService.authToken())
            .withParameters({
                $method: 'POST',
                $encoding: 'JSON',
                $data: postData("getShiftsForWeek",[])
            });

        return manager.executeQuery(query).then(
            function (data) {
                return data;
            },
            function (reject) {
                console.log(reject);
            }
        )
    }

});

我的index.html

中包含了这些内容
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/breezejs/breeze.debug.js"></script>
<script src="lib/breeze.js.labs/breeze.angular.js"></script>
<script src="lib/breeze.js.labs/breeze.ajaxpost.js"></script>

2 个答案:

答案 0 :(得分:1)

你写了一个好玩的东西。它揭示了我在这里总结的一些错误和机会。

forked your plunker和&#34;修复它&#34;。它现在返回数据并在屏幕上显示。

我尽量不要改变太多,但我确实重新组织了一个看似我可读的风格。我首先在顶部显示完整的应用程序组件:

angular.module('myApp', ['breeze.angular'])
    .value('jsonResultsAdapter', createJsonResultsAdapter())
    .service('datacontext', DataContext)
    .service('model', Model)
    .controller('sitesCtrl', SitesCtrl) 
    //.config(configForCORS);

观察

CORS

您尝试为CORS(configForCors)配置浏览器对我的浏览器(IE10,Chrome,FF)没有任何影响。我认为它不会对你有所帮助。浏览器支持CORS,或者它不支持CORS。我还没有找到任何方法。如果你需要支持IE8,你就会遇到麻烦,因为它没有做CORS。

为Breeze配置 ajaxAdapter

&#39; breeze.angular&#39;模块为你做到了。将该模块包含为依赖项(angular.module('myApp', ['breeze.angular'])),然后注入“微风”#39;只需要为第一个需要微风的服务(例如Datacontext)提供服务即可。

为POST查询配置Breeze

Breeze默认将查询请求作为GET请求发送。您的服务需要POST请求。微风可以做到这一点。

您忽略了 index.html 中包含 breeze.ajaxpost.js 库脚本标记。您需要使用Breeze Labs插件来进行POST查询。

你还必须告诉Angular ajaxAdapter。查看DataContext#configAjaxAdapter。你会看到:

    // configure that adapter to use ajaxPost plugin
    breeze.ajaxpost(ajaxAdapter);

实际上,您不需要指定ajax适配器; breeze将启用POST查询支持当前默认的ajax适配器实例 ,如果你写这个:

    // configure that adapter to use ajaxPost plugin
    breeze.ajaxpost();

但我更明确,因为我必须得到ajax适配器才能设置默认标头:

    // default ajax adapter is already a wrapper around current $http
    // as a result of injecting the breeze service.
    var ajaxAdapter = breeze.config.getAdapterInstance("ajax");

    // add the app-specific default headers
    // no need to set "Content-Type" for JSON; breeze does that by default
    ajaxAdapter.defaultSettings = {
      headers: {
          "JsonStub-User-Key": "2d3b6e81-b556-4049-ab54-ec8422237c63",
          "JsonStub-Project-Key": "a753777a-bbff-4db6-8755-ea8c5e60f032"            
      }
    };
  

注意我拨打了getAdapterInstance,而不是initializeAdapterInstance。我们希望修改由breeze.angular创建的现有实例,而不是用新的实例覆盖它。

客户端元数据和jsonResultsAdapter

进行这些更改后,我从服务中获取数据。不幸的是, 该数据的形状与jsonResultsAdapter或元数据中的期望并不完全匹配。

JSON到达具有pathwaySchool属性的对象。该属性返回一个数组。该数组包含感兴趣的实体数据;数组本身是无用的,不应该成为Breeze entityType。

我训练了&#39; jsonResultsAdapter.visitNode&#39;使用&#34; buildingCode&#34;识别对象的方法属性。这些对象包含PathwaySchool个实体的数据......我们这样说就是为这些节点返回{entityType: "PathwaySchool"}

Patrick的元数据描述了一个名为&#34; Site&#34;的类型。但是他的jsonResultsAdapter称这种类型为&#34; PathwaySchool&#34;。不得不称之为一件事或另一件事。我选择了#34; PathwaySchool&#34;。

元数据还说我们应该期待&#34; _id&#34;作为实体键的属性。数据中没有这样的属性。 buildingCode属性看起来最像一个唯一标识符,因此我将该属性作为关键。我还添加了name属性,以便我们可以在屏幕上显示学校。

从ajax结果中提取实体

该服务返回一个深层嵌套的对象。 datacontext应该隐藏ViewModel / Controller中的混乱。

所以成功回调挖掘并提取了#34; PathwaySchool&#34; s。

 return data.results[0].pathwaySchool;

如果ajax调用失败,我们应该做点什么。失败回调将错误写入控制台(使用Angular&#39; $log服务以便将来测试),然后重新拒绝错误。

重新拒绝很重要!我们希望确保调用者看到错误,以便它可以适当地处理它。如果我们什么也没做,Angular会认为我们已经修复了错误并将undefined传递给了调用者的成功回调。那不是我们想要的。我们希望将错误传递给调用者的失败回调。所以我们重新拒绝错误并返回那个(失败的)承诺。

视图模型/控制器

Patrick的控制器调用了datacontext并简单地将调用结果分配给$scope.sites数组,期望angular绑定到这些结果:

$scope.sites = datacontext.getSites(); // Not good!

那不会奏效。我们不希望Angular显示承诺。我们希望在promise与适当的实体解析后设置$scope.sites数组。

如果我们的数据调用失败,我们也应该准备好显示错误。

以下是我如何将网站纳入$scope

$scope.sites = [];

datacontext.getSites()
    .then(function(sites){
        $scope.error = ''; // clear previous error if any
        $scope.sites = sites;
    })
    .catch(function(error){
        $scope.error = "'getSites' failed: " + error.message +
        ". Check console log for details.";
    });

如果出现问题,视图可以绑定到$scope.error

查看绑定

最后,我们在屏幕上显示结果或错误。我需要少量的HTML用于此目的:

<div ng-controller="sitesCtrl">
  <div ng-repeat="site in sites">#{{site.buildingCode}} {{site.name}}</div>

  <p class="errorMessage" ng-if="error">{{error}}</p>    
</div>

答案 1 :(得分:0)

我在a passing test添加了ngDocCode sample {/ 3}}:

var resource = '/breeze/Northwind/CustomersWithFilterOptions?token=1234ABCD';

beforeEach(function () {
    breeze.ajaxpost(); // add POST option to ajax adapter
    em = newEm();      // fresh EntityManager before each test
});
...

it("by CompanyName w/ appended URL query string", function (done) {
    // See SO question
    // http://stackoverflow.com/questions/27364078/breezejs-datacontext-post-in-angular-turns-into-get
    var companyName = 'Die Wandernde Kuh';

    // Notice the query string appended to the resource
    EntityQuery.from(resource + '?token=1234ABCD')
        .withParameters({
            $method: 'POST',
            $encoding: 'JSON',
            $data: {
                CompanyName: companyName
            }
        })
        .using(em).execute()
        .then(success)
        .then(done, done);

    function success(data){
        expect(data.results).to.have.length(1);
        var cust = data.results[0];
        expect(cust.CompanyName).to.equal(companyName);
    }
});

网络上的请求如下所示:

POST /breeze/Northwind/CustomersWithFilterOptions?token=1234ABCD HTTP/1.1
Host: localhost:58066
Connection: keep-alive
Content-Length: 35
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8

请求有效负载是

{"CompanyName":"Die Wandernde Kuh"}

我不确定我们和你们之间有什么不同。但球在你的球场上提供了一个复制品(plunker或jsFiddle)。

我在你的问题代码中没有看到任何明显的东西。我不知道为什么你要注射$http,但那不应该受到伤害。

我不知道你在哪里依赖微风实验室&#39; breeze.angular&#39;模块,但你必须在某个地方做它或者Angular会失败(&#34;无法找到breezeProvider&#34;)当它注入&#34; breeze&#34;进入你的&#34; datacontext&#34;工厂。