我有一个工厂通过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>
答案 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(configForCors
)配置浏览器对我的浏览器(IE10,Chrome,FF)没有任何影响。我认为它不会对你有所帮助。浏览器支持CORS,或者它不支持CORS。我还没有找到任何方法。如果你需要支持IE8,你就会遇到麻烦,因为它没有做CORS。
&#39; breeze.angular&#39;模块为你做到了。将该模块包含为依赖项(angular.module('myApp', ['breeze.angular'])
),然后注入“微风”#39;只需要为第一个需要微风的服务(例如Datacontext
)提供服务即可。
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
或元数据中的期望并不完全匹配。
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
属性,以便我们可以在屏幕上显示学校。
该服务返回一个深层嵌套的对象。 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;工厂。