Ember-Data:如何“映射"?工作 [英] Ember-Data: How do "mappings" work

查看:17
本文介绍了Ember-Data:如何“映射"?工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试将一些东西与 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,名称":浪漫"}]

我不能确切地说出问题是什么,并且由于断言提到我需要映射,我想知道:

  1. 这个映射是什么以及如何使用它.
  2. 由于返回的 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:

  1. What this mapping is and how to use it.
  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆