Ember-Data:如何“映射"?工作 [英] Ember-Data: How do "mappings" work
问题描述
我目前正在尝试将一些东西与 ember + emberdata + 路由器 + asp.net web api 放在一起.大部分似乎都可以工作,但是当 ember-data 尝试通过我的模型的适配器 findAll
时,我遇到了一条错误消息.
在我的后端,我有一个这样的模型(C#):
公共类流派{[钥匙]公共 int Id { 获取;放;}[必需的][StringLength(50, MinimumLength=3)]公共字符串名称 { 获取;放;}}
在我的应用程序中,我使用 ember-data 表示它:
App.Genre = DS.Model.extend({id: DS.attr("number"),名称:DS.attr("string")}).reopenClass({网址:'api/流派'});
我还在我的应用程序中使用 RESTAdapter 定义了一个商店,如下所示:
App.store = DS.Store.create({修订:4,适配器:DS.RESTAdapter.create({批量提交:假})});
商店在我的控制器中使用如下:
App.GenreController = Ember.ArrayController.extend({内容:App.store.findAll(App.Genre),selectedGenre: 空});
路由器定义为
App.router = Em.Router.create({enableLogging: 真,位置:'哈希',根:Ember.Route.extend({//...流派:Em.Route.extend({路线:'/流派',索引:Ember.Route.extend({connectOutlets:功能(路由器,上下文){router.get('applicationController').connectOutlet('genre');}})}),//...})})
当我运行我的应用程序时,对于每个具有相同结构的对象,我都会收到以下消息:
<块引用>未捕获的错误:断言失败:您的服务器返回了一个哈希值键 0 但你没有映射
作为参考,这里是服务返回的 json:
<预><代码>[{身份证":1,"name": "动作"},{身份证":2,"name": "剧情"},{身份证":3,名称":喜剧"},{身份证":4,名称":浪漫"}]我不能确切地说出问题是什么,并且由于断言提到我需要映射,我想知道:
- 这个映射是什么以及如何使用它.
- 由于返回的 json 是一个数组,我应该在我的应用程序中使用不同类型的控制器,还是在 ember-data 中使用这种类型的 json 时我应该知道什么?还是应该更改服务器中的 JsonFormatter 选项?
欢迎任何帮助.
如果您觉得这还不足以理解问题,我当然可以添加更多信息.
编辑:我在后端更改了一些内容,现在服务器中的 findAll()
等效操作将输出序列化为以下 json:
<代码>{流派":[{ "id": 1, "name": "Action" },{ "id": 2, "name": "戏剧" },{ "id": 3, "name": "喜剧" },{ "id": 4, "name": "浪漫" }]}
但我仍然无法让它在客户端中填充我的模型,并且我的错误消息已更改为:
<块引用>未捕获的错误:断言失败:您的服务器返回了一个哈希值关键流派,但你没有映射
不确定我还有什么地方做错了.
抛出这个异常的方法是sideload
并检查映射如下:
sideload: function (store, type, json, root) {var sideloadedType, 映射, 加载 = {};加载[root] = true;for(json中的var prop){if (!json.hasOwnProperty(prop)) { 继续;}如果(道具 === 根){ 继续;}sideloadedType = type.typeForAssociation(prop);如果 (!sideloadedType) {mappings = get(this, 'mappings');Ember.assert("你的服务器返回了一个带有键 " + prop + " 的哈希值,但你没有映射", !!mappings);//...
这个调用 sideloadedType = type.typeForAssociation(prop);
返回 undefined
然后我得到错误信息.方法 typeForAssociation()
检查 for 'associationsByName'
键,该键返回一个空的 Ember.Map
.
目前还没有解决方案.
顺便说一下...
我现在的动作是这样的:
//GET api/genres公共对象 GetGenres() {返回新 { 流派 = context.Genres.AsQueryable() };}//获取 api/流派//[可查询]//公共IQueryable<流派>获取流派()//{//返回 context.Genres.AsQueryable();//}
我不得不删除由 json.NET 序列化的原始实现,因为我找不到生成 json 输出的配置选项正如 Ember-Data 所期望的(如 {resource_name : [json, json,...]}
).这样做的副作用是我失去了内置的 OData 支持,但我想保留它.有谁知道我如何配置它为集合生成不同的 json?
映射可以在 DS.RESTAdapter 中定义.我想你可以尝试定义这样的东西:
App.Store = DS.Store.extend({适配器:DS.RESTAdapter.create({批量提交:真,映射:{流派:App.Genre},//你也可以定义复数,如果有不规则的复数//通常,RESTAdapter 简单地为复数添加一个s".//例如在工作中我们必须定义这样的东西复数:{业务流程:'业务流程'//否则它会尝试获取business_processs}}),修订:4});
希望这能解决您的问题.
更新:
目前还没有很好的文档记录,我不记得是我们自己阅读代码发现的,还是 Tom Dale 指出的.
无论如何,这是 的重点复数对于映射,我认为我们和你一样被同样的错误所驱动,要么我们尝试过,要么汤姆教我们这个.
I'm currently trying to put something together with ember + emberdata + router + asp.net web api. Most of it seem to work, however I stuck in an error message I get when ember-data tries to findAll
through the adapter for my models.
In my backend I have a model like this (C#):
public class Genre {
[Key]
public int Id { get; set; }
[Required]
[StringLength(50, MinimumLength=3)]
public string Name { get; set; }
}
Which in my app I represent it like this using ember-data:
App.Genre = DS.Model.extend({
id: DS.attr("number"),
name: DS.attr("string")
}).reopenClass({
url: 'api/genre'
});
I have also a Store defined in my App using the RESTAdapter like so:
App.store = DS.Store.create({
revision: 4,
adapter: DS.RESTAdapter.create({
bulkCommit: false
})
});
And the store is used in my controller as below:
App.GenreController = Ember.ArrayController.extend({
content: App.store.findAll(App.Genre),
selectedGenre: null
});
The router is defined as
App.router = Em.Router.create({
enableLogging: true,
location: 'hash',
root: Ember.Route.extend({
//...
genre: Em.Route.extend({
route: '/genre',
index: Ember.Route.extend({
connectOutlets: function (router, context) {
router.get('applicationController').connectOutlet('genre');
}
})
}),
//...
})
})
When I run my application, I get the following message for every object that has this same structure:
Uncaught Error: assertion failed: Your server returned a hash with the key 0 but you have no mappings
For reference, here's the json the service is returning:
[
{
"id": 1,
"name": "Action"
},
{
"id": 2,
"name": "Drama"
},
{
"id": 3,
"name": "Comedy"
},
{
"id": 4,
"name": "Romance"
}
]
I cannot tell exactly what the problem is and since the assertion is mentioning that I need mapping, I'd like to know:
- What this mapping is and how to use it.
- Since the returned json is an array, should I be using a different type of controller in my app ,or is there anything I should know about when working with this type of json in ember-data? or should I change the JsonFormatter options in the server?
Any help is welcome.
I can definitely add more information if you feel this isn't enough to understand the problem.
EDIT: I've changed a few things in my backend and now my findAll()
equivalent action in the server serializes the the output as the following json:
{
"genres": [
{ "id": 1, "name": "Action" },
{ "id": 2, "name": "Drama" },
{ "id": 3, "name": "Comedy" },
{ "id": 4, "name": "Romance" }
]
}
But I still can't get it to populate my models in the client and my error message has changed to this:
Uncaught Error: assertion failed: Your server returned a hash with the key genres but you have no mappings
Not sure what else I might be doing wrong.
The method that throws this exception is sideload
and checks for the mappings like this:
sideload: function (store, type, json, root) {
var sideloadedType, mappings, loaded = {};
loaded[root] = true;
for (var prop in json) {
if (!json.hasOwnProperty(prop)) { continue; }
if (prop === root) { continue; }
sideloadedType = type.typeForAssociation(prop);
if (!sideloadedType) {
mappings = get(this, 'mappings');
Ember.assert("Your server returned a hash with the key " + prop + " but you have no mappings", !!mappings);
//...
This call sideloadedType = type.typeForAssociation(prop);
returns undefined
and then I get the error message. The method typeForAssociation()
checks for the for 'associationsByName'
key which returns an empty Ember.Map
.
Still no solution for this at the moment.
By the way...
My action is now like this:
// GET api/genres
public object GetGenres() {
return new { genres = context.Genres.AsQueryable() };
}
// GET api/genres
//[Queryable]
//public IQueryable<Genre> GetGenres()
//{
// return context.Genres.AsQueryable();
//}
I had to remove the original implementation which gets serialized by json.NET as I could not find config options to produce a json output as Ember-Data expects ( as in {resource_name : [json, json,...]}
). Side effect of this is that I've lost built-in OData support, but I'd like to keep it. Does anyone know how could I configure it to produce different json for a collection?
The mapping can be defined in the DS.RESTAdapter. I think you could try to define something like this:
App.Store = DS.Store.extend({
adapter: DS.RESTAdapter.create({
bulkCommit: true,
mappings: {
genres: App.Genre
},
// you can also define plurals, if there is a unregular plural
// usually, RESTAdapter simply add a 's' for plurals.
// for example at work we have to define something like this
plurals: {
business_process: 'business_processes'
//else it tries to fetch business_processs
}
}),
revision: 4
});
Hope this resolves your problem.
Update:
At this time, this is not well documented, I don't remember if we found it by ourself reading the code, or perhaps Tom Dale pointed on it.
Anyway, here is the point for plurals
For the mappings, I think we were driven by the same error as you, and either we tried, either Tom teached us about this.
这篇关于Ember-Data:如何“映射"?工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!